<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://techbase.kde.org/skins/common/feed.css?0.2"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://techbase.kde.org/api.php?action=feedcontributions&amp;user=Yecril71pl&amp;feedformat=atom</id>
		<title>KDE TechBase - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://techbase.kde.org/api.php?action=feedcontributions&amp;user=Yecril71pl&amp;feedformat=atom"/>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Special:Contributions/Yecril71pl"/>
		<updated>2013-05-24T12:25:08Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.20.2</generator>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/First_program</id>
		<title>Development/Tutorials/First program</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/First_program"/>
				<updated>2012-03-12T20:08:49Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* The Code */ oops, dead code&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Tutorials/First_program}}&lt;br /&gt;
{{TutorialBrowser|&lt;br /&gt;
&lt;br /&gt;
series=Beginner Tutorial|&lt;br /&gt;
&lt;br /&gt;
name=Hello World|&lt;br /&gt;
&lt;br /&gt;
pre=[http://mindview.net/Books/TICPP/ThinkingInCPP2e.html C++], [http://qt.nokia.com Qt], [[Getting_Started/Build|Building KDE]]|&lt;br /&gt;
&lt;br /&gt;
next=[[Development/Tutorials/Using_KXmlGuiWindow|Tutorial 2 - KXmlGuiWindow]]| &lt;br /&gt;
&lt;br /&gt;
reading=[[Development/Tutorials/CMake|CMake]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
Your first program shall greet the world with a friendly &amp;quot;Hello World&amp;quot;, what else? For that, we will use a {{class|KMessageBox}} and customise one of the buttons.&lt;br /&gt;
[[image:introtokdetutorial1.png|frame|center]]&lt;br /&gt;
&lt;br /&gt;
{{tip|To get more information about any class you come across, Konqueror offers a quick shortcut. So to look for information about KMessageBox, just type &amp;quot;kde:kmessagebox&amp;quot; into Konqueror and you'll be taken to the documentation.}}&lt;br /&gt;
&lt;br /&gt;
{{tip|&lt;br /&gt;
You might want to use [[qtcreator|QtCreator]] as IDE for your projects.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==The Code==&lt;br /&gt;
All the code we need will be in one file, &amp;lt;tt&amp;gt;main.cpp&amp;lt;/tt&amp;gt;. Create that file with the code below:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp-qt&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;cstdlib&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;KApplication&amp;gt;&lt;br /&gt;
#include &amp;lt;KAboutData&amp;gt;&lt;br /&gt;
#include &amp;lt;KCmdLineArgs&amp;gt;&lt;br /&gt;
#include &amp;lt;KMessageBox&amp;gt;&lt;br /&gt;
#include &amp;lt;KLocale&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
    KAboutData aboutData(&lt;br /&gt;
                         // The program name used internally.&lt;br /&gt;
                         &amp;quot;tutorial1&amp;quot;,&lt;br /&gt;
                         // The message catalog name&lt;br /&gt;
                         // If null, program name is used instead.&lt;br /&gt;
                         0,&lt;br /&gt;
                         // A displayable program name string.&lt;br /&gt;
                         ki18n(&amp;quot;Tutorial 1&amp;quot;),&lt;br /&gt;
                         // The program version string.&lt;br /&gt;
                         &amp;quot;1.0&amp;quot;,&lt;br /&gt;
                         // Short description of what the app does.&lt;br /&gt;
                         ki18n(&amp;quot;Displays a KMessageBox popup&amp;quot;),&lt;br /&gt;
                         // The license this code is released under&lt;br /&gt;
                         KAboutData::License_GPL,&lt;br /&gt;
                         // Copyright Statement&lt;br /&gt;
                         ki18n(&amp;quot;(c) 2007&amp;quot;),&lt;br /&gt;
                         // Optional text shown in the About box.&lt;br /&gt;
                         // Can contain any information desired.&lt;br /&gt;
                         ki18n(&amp;quot;Some text...&amp;quot;),&lt;br /&gt;
                         // The program homepage string.&lt;br /&gt;
                         &amp;quot;http://example.com/&amp;quot;,&lt;br /&gt;
                         // The bug report email address&lt;br /&gt;
                         &amp;quot;submit@bugs.kde.org&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    KCmdLineArgs::init( argc, argv, &amp;amp;aboutData );&lt;br /&gt;
    KApplication app;&lt;br /&gt;
    KGuiItem yesButton( i18n( &amp;quot;Hello&amp;quot; ), QString(),&lt;br /&gt;
                        i18n( &amp;quot;This is a tooltip&amp;quot; ),&lt;br /&gt;
                        i18n( &amp;quot;This is a WhatsThis help text.&amp;quot; ) );&lt;br /&gt;
    return &lt;br /&gt;
        KMessageBox ::questionYesNo &lt;br /&gt;
        (0, i18n( &amp;quot;Hello World&amp;quot; ), i18n( &amp;quot;Hello&amp;quot; ), yesButton ) &lt;br /&gt;
        == KMessageBox ::Yes? EXIT_SUCCESS: EXIT_FAILURE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The first KDE specific code we come across in this program is {{class|KAboutData}}. This is the class used to store information about the program such as a short description, authors or license information. Pretty much every KDE application should use this class.&lt;br /&gt;
&lt;br /&gt;
Then we come to {{class|KCmdLineArgs}}. This is the class one would use to specify command line switches to, for example, open the program with a specific file. However, in this tutorial, we simply initialise it with the {{class|KAboutData}} object we created so we can use the &amp;lt;tt&amp;gt;--version&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;--author&amp;lt;/tt&amp;gt; switches.&lt;br /&gt;
&lt;br /&gt;
Then we create a {{class|KApplication}} object. This needs to be done exactly once in each program since it is needed for things such as [[Development/Tutorials/Localization/i18n|i18n]].&lt;br /&gt;
&lt;br /&gt;
Now we've done all the necessary KDE setup, we can move on to doing interesting things with our application. We're going to create a popup box but we're going to customise one of the buttons. To do this customisation, we need to use a {{class|KGuiItem}} object. The first argument in the {{class|KGuiItem}} constructor is the text that will appear on the item (in our case, a button). Then we have an option of setting an icon for the button but we don't want one so we just give it &amp;lt;tt&amp;gt;QString()&amp;lt;/tt&amp;gt;. We then set the tooltip (what appears when you hover over an item) and finally the &amp;quot;What's This?&amp;quot; (accessed through right-clicking or Shift-F1) text.&lt;br /&gt;
&lt;br /&gt;
Now we have our item, we can create our popup. We call the &amp;lt;tt&amp;gt;{{class|KMessageBox}}::questionYesNo()&amp;lt;/tt&amp;gt; function which, by default, creates a message box with a &amp;quot;Yes&amp;quot; and a &amp;quot;No&amp;quot; button. The second argument is the text that will appear in the message box above the buttons. The third is the caption the window will have and finally we set the KGuiItem for (what would normally be) the &amp;quot;Yes&amp;quot; button to the &amp;lt;tt&amp;gt;KGuiItem yesButton&amp;lt;/tt&amp;gt; we created.&lt;br /&gt;
&lt;br /&gt;
Note that all user-visible text is passed through the i18n() function; this is necessary for the UI to be translatable. More information on localization can be found in the [[Development/Tutorials/Localization/i18n|localization tutorial]].&lt;br /&gt;
&lt;br /&gt;
We're all done as far as the code is concerned. Now to build it and try it out.&lt;br /&gt;
&lt;br /&gt;
== Build ==&lt;br /&gt;
You want to [[Development/Tutorials/CMake|use CMake]] for your build environment. You provide a file CMakeLists.txt, cmake uses this file to generate all Makefiles out of it.&lt;br /&gt;
&lt;br /&gt;
=== CMakeLists.txt ===&lt;br /&gt;
Create a file named CMakeLists.txt in the same directory as main.cpp with this content:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cmake&amp;quot;&amp;gt;&lt;br /&gt;
project (tutorial1)&lt;br /&gt;
find_package(KDE4 REQUIRED)&lt;br /&gt;
include (KDE4Defaults)&lt;br /&gt;
include_directories(${KDE4_INCLUDES})&lt;br /&gt;
set(tutorial1_SRCS main.cpp)&lt;br /&gt;
kde4_add_executable(tutorial1 ${tutorial1_SRCS})&lt;br /&gt;
target_link_libraries(tutorial1 ${KDE4_KDEUI_LIBS})&lt;br /&gt;
install(TARGETS tutorial1  ${INSTALL_TARGETS_DEFAULT_ARGS})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The &amp;lt;tt&amp;gt;find_package()&amp;lt;/tt&amp;gt; function locates the package that you ask it for (in this case KDE4) and sets some variables describing the location of the package's headers and libraries. In this case we will use the &amp;lt;tt&amp;gt;KDE4_INCLUDES&amp;lt;/tt&amp;gt; variable which contains the path to the KDE4 header files.&lt;br /&gt;
&lt;br /&gt;
In order to allow the compiler to find these files, we pass that variable to the &amp;lt;tt&amp;gt;include_directories()&amp;lt;/tt&amp;gt; function which adds the KDE4 headers to the header search path.&lt;br /&gt;
&lt;br /&gt;
Next we create a variable called &amp;lt;tt&amp;gt;tutorial1_SRCS&amp;lt;/tt&amp;gt; using the &amp;lt;tt&amp;gt;set()&amp;lt;/tt&amp;gt; function. In this case we simply set it to the name of our only source file.&lt;br /&gt;
&lt;br /&gt;
Then we use &amp;lt;tt&amp;gt;kde4_add_executable()&amp;lt;/tt&amp;gt; to create an executable called &amp;lt;tt&amp;gt;tutorial1&amp;lt;/tt&amp;gt; from the source files listed in our &amp;lt;tt&amp;gt;tutorial1_SRCS&amp;lt;/tt&amp;gt; variable. Afterwards, we link our executable to the KDE4 kdeui library using &amp;lt;tt&amp;gt;target_link_libraries()&amp;lt;/tt&amp;gt; and the &amp;lt;tt&amp;gt;KDE4_KDEUI_LIBS&amp;lt;/tt&amp;gt; variable which was set by the &amp;lt;tt&amp;gt;find_package()&amp;lt;/tt&amp;gt; function. The line starting with &amp;lt;tt&amp;gt;install&amp;lt;/tt&amp;gt; writes a default &amp;quot;install&amp;quot; target into the Makefile.&lt;br /&gt;
&lt;br /&gt;
=== Make And Run ===&lt;br /&gt;
To compile, link and install your program, you must have several software installed, e.g. kdelibs, cmake, make and gcc-c++. To be sure you have everything, best follow [[Getting_Started/Build/Environment|this install guide]].&lt;br /&gt;
&lt;br /&gt;
You can invoke CMake and make manually:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cmake . &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Or, if you set up your environment as described in [[Getting_Started/Build/Environment|Getting Started/Build/Environment]], you can compile this code with:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cmakekde&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And launch it with:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./tutorial1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Moving On==&lt;br /&gt;
Now you can move on to [[Development/Tutorials/Using_KXmlGuiWindow|using KXmlGuiWindow]].&lt;br /&gt;
&lt;br /&gt;
[[Category:C++]]&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/First_program</id>
		<title>Development/Tutorials/First program</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/First_program"/>
				<updated>2012-03-12T20:07:55Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* The Code */ return failure on No&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Tutorials/First_program}}&lt;br /&gt;
{{TutorialBrowser|&lt;br /&gt;
&lt;br /&gt;
series=Beginner Tutorial|&lt;br /&gt;
&lt;br /&gt;
name=Hello World|&lt;br /&gt;
&lt;br /&gt;
pre=[http://mindview.net/Books/TICPP/ThinkingInCPP2e.html C++], [http://qt.nokia.com Qt], [[Getting_Started/Build|Building KDE]]|&lt;br /&gt;
&lt;br /&gt;
next=[[Development/Tutorials/Using_KXmlGuiWindow|Tutorial 2 - KXmlGuiWindow]]| &lt;br /&gt;
&lt;br /&gt;
reading=[[Development/Tutorials/CMake|CMake]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
Your first program shall greet the world with a friendly &amp;quot;Hello World&amp;quot;, what else? For that, we will use a {{class|KMessageBox}} and customise one of the buttons.&lt;br /&gt;
[[image:introtokdetutorial1.png|frame|center]]&lt;br /&gt;
&lt;br /&gt;
{{tip|To get more information about any class you come across, Konqueror offers a quick shortcut. So to look for information about KMessageBox, just type &amp;quot;kde:kmessagebox&amp;quot; into Konqueror and you'll be taken to the documentation.}}&lt;br /&gt;
&lt;br /&gt;
{{tip|&lt;br /&gt;
You might want to use [[qtcreator|QtCreator]] as IDE for your projects.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==The Code==&lt;br /&gt;
All the code we need will be in one file, &amp;lt;tt&amp;gt;main.cpp&amp;lt;/tt&amp;gt;. Create that file with the code below:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp-qt&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;cstdlib&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;KApplication&amp;gt;&lt;br /&gt;
#include &amp;lt;KAboutData&amp;gt;&lt;br /&gt;
#include &amp;lt;KCmdLineArgs&amp;gt;&lt;br /&gt;
#include &amp;lt;KMessageBox&amp;gt;&lt;br /&gt;
#include &amp;lt;KLocale&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
    KAboutData aboutData(&lt;br /&gt;
                         // The program name used internally.&lt;br /&gt;
                         &amp;quot;tutorial1&amp;quot;,&lt;br /&gt;
                         // The message catalog name&lt;br /&gt;
                         // If null, program name is used instead.&lt;br /&gt;
                         0,&lt;br /&gt;
                         // A displayable program name string.&lt;br /&gt;
                         ki18n(&amp;quot;Tutorial 1&amp;quot;),&lt;br /&gt;
                         // The program version string.&lt;br /&gt;
                         &amp;quot;1.0&amp;quot;,&lt;br /&gt;
                         // Short description of what the app does.&lt;br /&gt;
                         ki18n(&amp;quot;Displays a KMessageBox popup&amp;quot;),&lt;br /&gt;
                         // The license this code is released under&lt;br /&gt;
                         KAboutData::License_GPL,&lt;br /&gt;
                         // Copyright Statement&lt;br /&gt;
                         ki18n(&amp;quot;(c) 2007&amp;quot;),&lt;br /&gt;
                         // Optional text shown in the About box.&lt;br /&gt;
                         // Can contain any information desired.&lt;br /&gt;
                         ki18n(&amp;quot;Some text...&amp;quot;),&lt;br /&gt;
                         // The program homepage string.&lt;br /&gt;
                         &amp;quot;http://example.com/&amp;quot;,&lt;br /&gt;
                         // The bug report email address&lt;br /&gt;
                         &amp;quot;submit@bugs.kde.org&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    KCmdLineArgs::init( argc, argv, &amp;amp;aboutData );&lt;br /&gt;
    KApplication app;&lt;br /&gt;
    KGuiItem yesButton( i18n( &amp;quot;Hello&amp;quot; ), QString(),&lt;br /&gt;
                        i18n( &amp;quot;This is a tooltip&amp;quot; ),&lt;br /&gt;
                        i18n( &amp;quot;This is a WhatsThis help text.&amp;quot; ) );&lt;br /&gt;
    return &lt;br /&gt;
        KMessageBox ::questionYesNo &lt;br /&gt;
        (0, i18n( &amp;quot;Hello World&amp;quot; ), i18n( &amp;quot;Hello&amp;quot; ), yesButton ) &lt;br /&gt;
        == KMessageBox ::Yes? EXIT_SUCCESS: EXIT_FAILURE;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The first KDE specific code we come across in this program is {{class|KAboutData}}. This is the class used to store information about the program such as a short description, authors or license information. Pretty much every KDE application should use this class.&lt;br /&gt;
&lt;br /&gt;
Then we come to {{class|KCmdLineArgs}}. This is the class one would use to specify command line switches to, for example, open the program with a specific file. However, in this tutorial, we simply initialise it with the {{class|KAboutData}} object we created so we can use the &amp;lt;tt&amp;gt;--version&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;--author&amp;lt;/tt&amp;gt; switches.&lt;br /&gt;
&lt;br /&gt;
Then we create a {{class|KApplication}} object. This needs to be done exactly once in each program since it is needed for things such as [[Development/Tutorials/Localization/i18n|i18n]].&lt;br /&gt;
&lt;br /&gt;
Now we've done all the necessary KDE setup, we can move on to doing interesting things with our application. We're going to create a popup box but we're going to customise one of the buttons. To do this customisation, we need to use a {{class|KGuiItem}} object. The first argument in the {{class|KGuiItem}} constructor is the text that will appear on the item (in our case, a button). Then we have an option of setting an icon for the button but we don't want one so we just give it &amp;lt;tt&amp;gt;QString()&amp;lt;/tt&amp;gt;. We then set the tooltip (what appears when you hover over an item) and finally the &amp;quot;What's This?&amp;quot; (accessed through right-clicking or Shift-F1) text.&lt;br /&gt;
&lt;br /&gt;
Now we have our item, we can create our popup. We call the &amp;lt;tt&amp;gt;{{class|KMessageBox}}::questionYesNo()&amp;lt;/tt&amp;gt; function which, by default, creates a message box with a &amp;quot;Yes&amp;quot; and a &amp;quot;No&amp;quot; button. The second argument is the text that will appear in the message box above the buttons. The third is the caption the window will have and finally we set the KGuiItem for (what would normally be) the &amp;quot;Yes&amp;quot; button to the &amp;lt;tt&amp;gt;KGuiItem yesButton&amp;lt;/tt&amp;gt; we created.&lt;br /&gt;
&lt;br /&gt;
Note that all user-visible text is passed through the i18n() function; this is necessary for the UI to be translatable. More information on localization can be found in the [[Development/Tutorials/Localization/i18n|localization tutorial]].&lt;br /&gt;
&lt;br /&gt;
We're all done as far as the code is concerned. Now to build it and try it out.&lt;br /&gt;
&lt;br /&gt;
== Build ==&lt;br /&gt;
You want to [[Development/Tutorials/CMake|use CMake]] for your build environment. You provide a file CMakeLists.txt, cmake uses this file to generate all Makefiles out of it.&lt;br /&gt;
&lt;br /&gt;
=== CMakeLists.txt ===&lt;br /&gt;
Create a file named CMakeLists.txt in the same directory as main.cpp with this content:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cmake&amp;quot;&amp;gt;&lt;br /&gt;
project (tutorial1)&lt;br /&gt;
find_package(KDE4 REQUIRED)&lt;br /&gt;
include (KDE4Defaults)&lt;br /&gt;
include_directories(${KDE4_INCLUDES})&lt;br /&gt;
set(tutorial1_SRCS main.cpp)&lt;br /&gt;
kde4_add_executable(tutorial1 ${tutorial1_SRCS})&lt;br /&gt;
target_link_libraries(tutorial1 ${KDE4_KDEUI_LIBS})&lt;br /&gt;
install(TARGETS tutorial1  ${INSTALL_TARGETS_DEFAULT_ARGS})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The &amp;lt;tt&amp;gt;find_package()&amp;lt;/tt&amp;gt; function locates the package that you ask it for (in this case KDE4) and sets some variables describing the location of the package's headers and libraries. In this case we will use the &amp;lt;tt&amp;gt;KDE4_INCLUDES&amp;lt;/tt&amp;gt; variable which contains the path to the KDE4 header files.&lt;br /&gt;
&lt;br /&gt;
In order to allow the compiler to find these files, we pass that variable to the &amp;lt;tt&amp;gt;include_directories()&amp;lt;/tt&amp;gt; function which adds the KDE4 headers to the header search path.&lt;br /&gt;
&lt;br /&gt;
Next we create a variable called &amp;lt;tt&amp;gt;tutorial1_SRCS&amp;lt;/tt&amp;gt; using the &amp;lt;tt&amp;gt;set()&amp;lt;/tt&amp;gt; function. In this case we simply set it to the name of our only source file.&lt;br /&gt;
&lt;br /&gt;
Then we use &amp;lt;tt&amp;gt;kde4_add_executable()&amp;lt;/tt&amp;gt; to create an executable called &amp;lt;tt&amp;gt;tutorial1&amp;lt;/tt&amp;gt; from the source files listed in our &amp;lt;tt&amp;gt;tutorial1_SRCS&amp;lt;/tt&amp;gt; variable. Afterwards, we link our executable to the KDE4 kdeui library using &amp;lt;tt&amp;gt;target_link_libraries()&amp;lt;/tt&amp;gt; and the &amp;lt;tt&amp;gt;KDE4_KDEUI_LIBS&amp;lt;/tt&amp;gt; variable which was set by the &amp;lt;tt&amp;gt;find_package()&amp;lt;/tt&amp;gt; function. The line starting with &amp;lt;tt&amp;gt;install&amp;lt;/tt&amp;gt; writes a default &amp;quot;install&amp;quot; target into the Makefile.&lt;br /&gt;
&lt;br /&gt;
=== Make And Run ===&lt;br /&gt;
To compile, link and install your program, you must have several software installed, e.g. kdelibs, cmake, make and gcc-c++. To be sure you have everything, best follow [[Getting_Started/Build/Environment|this install guide]].&lt;br /&gt;
&lt;br /&gt;
You can invoke CMake and make manually:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cmake . &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Or, if you set up your environment as described in [[Getting_Started/Build/Environment|Getting Started/Build/Environment]], you can compile this code with:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cmakekde&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And launch it with:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./tutorial1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Moving On==&lt;br /&gt;
Now you can move on to [[Development/Tutorials/Using_KXmlGuiWindow|using KXmlGuiWindow]].&lt;br /&gt;
&lt;br /&gt;
[[Category:C++]]&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/PIM/KDE_4-related_bugs</id>
		<title>Projects/PIM/KDE 4-related bugs</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/PIM/KDE_4-related_bugs"/>
				<updated>2012-02-14T11:11:39Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: green is too dark&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Major bugs / Showstoppers ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Small description !! Additional comments !! Status&lt;br /&gt;
|-&lt;br /&gt;
|Kontact plugin selection totally broken||kdelibs [http://bugs.kde.org/show_bug.cgi?id=152326 bug 152326] and [http://bugs.kde.org/show_bug.cgi?id=152495 bug 152495] ||not started&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|KNode: Can't post messages, refused with &amp;quot;You cannot post an empty message.&amp;quot;||Needs to be fixed before release||claimed to be fixed, was kdelibs bug&lt;br /&gt;
|-&lt;br /&gt;
|Akregator: Articles appear in wrong feed, articles get randomly marked as unread again||[https://bugs.kde.org/show_bug.cgi?id=161313 Bug report]||not started&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Bugs ==&lt;br /&gt;
=== Kontact ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Small description !! Additional comments !! Status&lt;br /&gt;
|-&lt;br /&gt;
|Mainwindow size changes when switching components|| || not started&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Reverse name with comma&amp;quot; setting of KAddressbook doesn't seem to be honored by KMail's composer||||not started&lt;br /&gt;
|-&lt;br /&gt;
|Progressbar takes too much space||||not started&lt;br /&gt;
|-&lt;br /&gt;
|Wrong layout for configure dialog: side pane does not have enough space||||[http://bugs.kde.org/show_bug.cgi?id=152326 kdelibs bug]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;xx contacts matching&amp;quot; message of the addressbook component added to the wrong place in the status bar||||not started&lt;br /&gt;
|-&lt;br /&gt;
|Unable to change date range of special dates plugin||||not started&lt;br /&gt;
|-&lt;br /&gt;
|Date in summary no longer right-aligned||||not started&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== KOrganizer ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Small description !! Additional comments !! Status&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Creating all-day events does not have any effect||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Changing month in date-picker in top-left corner: Layout is changed because of different length of month names||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Date-picker in top-left corner: Year has semicolon (2,008 instead of 2008)||||fixed&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== KMail ===&lt;br /&gt;
&lt;br /&gt;
See also the bugzilla reports, KDE4 specifc bugs can be viewed with&lt;br /&gt;
[https://bugs.kde.org/buglist.cgi?short_desc_type=allwordssubstr&amp;amp;short_desc=&amp;amp;long_desc_type=allwordssubstr&amp;amp;long_desc=&amp;amp;product=kmail&amp;amp;version=1.9.50&amp;amp;version=1.9.51&amp;amp;version=1.10.0&amp;amp;version=1.9.52&amp;amp;version=SVN+trunk+%28KDE+4%29&amp;amp;bug_status=UNCONFIRMED&amp;amp;bug_status=NEW&amp;amp;bug_status=ASSIGNED&amp;amp;bug_status=REOPENED&amp;amp;bug_severity=critical&amp;amp;bug_severity=grave&amp;amp;bug_severity=major&amp;amp;bug_severity=crash&amp;amp;bug_severity=normal&amp;amp;bug_severity=minor&amp;amp;bugidtype=include&amp;amp;bug_id=&amp;amp;votes=&amp;amp;emailassigned_to1=1&amp;amp;emailtype1=substring&amp;amp;email1=&amp;amp;emailassigned_to2=1&amp;amp;emailreporter2=1&amp;amp;emailcc2=1&amp;amp;emailtype2=substring&amp;amp;email2=&amp;amp;changedin=&amp;amp;chfieldfrom=&amp;amp;chfieldto=Now&amp;amp;chfieldvalue=&amp;amp;order=Reuse+same+sort+as+last+time&amp;amp;cmdtype=doit  this query]&lt;br /&gt;
&lt;br /&gt;
Open reports with patches: [https://bugs.kde.org/buglist.cgi?short_desc_type=allwordssubstr&amp;amp;short_desc=PATCH&amp;amp;long_desc_type=allwordssubstr&amp;amp;long_desc=&amp;amp;product=kmail&amp;amp;bug_status=UNCONFIRMED&amp;amp;bug_status=NEW&amp;amp;bug_status=ASSIGNED&amp;amp;bug_status=REOPENED&amp;amp;bugidtype=include&amp;amp;bug_id=&amp;amp;votes=&amp;amp;emailassigned_to1=1&amp;amp;emailtype1=substring&amp;amp;email1=&amp;amp;emailassigned_to2=1&amp;amp;emailreporter2=1&amp;amp;emailcc2=1&amp;amp;emailtype2=substring&amp;amp;email2=&amp;amp;changedin=&amp;amp;chfieldfrom=&amp;amp;chfieldto=Now&amp;amp;chfieldvalue=&amp;amp;order=Reuse+same+sort+as+last+time&amp;amp;cmdtype=doit Query]&lt;br /&gt;
&lt;br /&gt;
If you are not a developer, please don't report bugs here, there is not enough space for meaningful reports; use bugs.kde.org instead.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Small description !! Additional comments !! Status&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Editor: HTML Toolbar does not have &amp;quot;Standard&amp;quot; as default bullet type, the combobox is empty.||||fixed&lt;br /&gt;
|-&lt;br /&gt;
|Template Config: Dialog size changes when changing shortcut||||not started&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|After checking mail with POP3, clicking a message results in many setMsg() calls, which is slow||Multiple connects?||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Composer: HTML toolbar should be in separate row||||fixed&lt;br /&gt;
|-&lt;br /&gt;
|Crash when canceling POP3 check quickly||Somewhere in scheduler||not started&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|&amp;lt;message&amp;gt; and &amp;lt;body&amp;gt; filter criteria missing||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Some messages (fetched with POP) have strange character as last char of subject in message list||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|No longer possible to expand folder without selecting it||according to till. Not seen on r827329||fixed&lt;br /&gt;
|-&lt;br /&gt;
|POP3: Fetching mail does not work when precommand is enabled||||not started&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|POP account dialog: editing &amp;quot;filter if greater than xx bytes&amp;quot; keyboard input broken||KDELIBS bugs really, but very annoying. Used in other places as well.||fixed&lt;br /&gt;
|-&lt;br /&gt;
|Composer: When sending message, the dialog that shows the used encryption keys has a broken layout||||not started&lt;br /&gt;
|-&lt;br /&gt;
|Appearance options: Message List-&amp;gt;Custom Format: Layout broken||||not started&lt;br /&gt;
|-&lt;br /&gt;
|Shortcut configured in stand-alone KMail are not loaded in Kontact - and the other way round||||not started&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Editor: Spellchecking config: Language change does not update the words marked with red||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Editor: Add/Remove quote char does not work for &amp;gt; 1 line or HTML text||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Editor: HTML toolbar enabled by default, state not correctly saved and inconsistent||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Editor: Editing draft/outgoing message causes HTML garbage to appear||||Fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Editor: Changing identity: Signature not changed when in HTML mode||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Editor: When writing new mail in HTML mode, no newline is added in front of the signature separator||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Editor: Quoted HTML text (after reply) no longer green||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Editor: Toggle fixed font does not work||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Editor: Right-clicking selects word||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Editor: Tabs show as spaces||||seems fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Editor: Mails are sent as HTML with incorrect content-type||||Fixed&lt;br /&gt;
|-&lt;br /&gt;
|Crash when deleting mail in maildir folder ||Two slightly different stack traces: http://pastebin.ca/800711 http://pastebin.ca/800740||not started&lt;br /&gt;
|-&lt;br /&gt;
|Crash when changing tag shortcut.||Set a shortcut, apply, reset the shortcut, apply, then set back the old one -&amp;gt; crash||not started&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Incorrect mainwindow size||resize() should be called in kmmainwin, not kmmainwidget||fixed&lt;br /&gt;
|-&lt;br /&gt;
|Pasting obsocufated mail address like &amp;quot;null at kde dot org&amp;quot; in 'to' line no longer changes it to real address||Seems not possible to fix, see [http://thread.gmane.org/gmane.comp.kde.devel.pim/20997 this thread]||not started&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Toggling unread column with right click on header: Action state not updated||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|inbox folder not created until restart when creating first pop account||||feature, not a bug :)&lt;br /&gt;
|-&lt;br /&gt;
|The composer needs to be restarted to see new addressbooks||||not started&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|POP filter dialog too small||||fixed&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Create Task&amp;quot; in stand-alone KMail does not start KOrganizer||The dbus autostarter in kdelibs does not work for some reason||not started&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Initial column sizes of the folder tree wrong||Size and unread column should be hidden by default||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|D-Bus interface broken, incorrect and incomplete port||See [http://article.gmane.org/gmane.comp.kde.devel.pim/20563 here] and [http://article.gmane.org/gmane.comp.kde.devel.pim/20592 here]||mostly fixed&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;Mark Message&amp;quot; entry in context menu sometimes takes several seconds to pop up||||not started&lt;br /&gt;
|-&lt;br /&gt;
|Alternate background colors in message list no longer there||Will probably be fixed in the SoC by Szymon||not started&lt;br /&gt;
|-&lt;br /&gt;
|Folder shortcuts don't work after restart if they were conflicting with another shortcut||||not started&lt;br /&gt;
|-&lt;br /&gt;
|Adding filter actions or folder shortcut actions manually to the toolbar does not work||does not survive a restart||not started&lt;br /&gt;
|-&lt;br /&gt;
|Tag shortcuts don't show up in &amp;quot;Configure Shortcuts&amp;quot; dialog||||not started&lt;br /&gt;
|-&lt;br /&gt;
|Renaming a transport: Identity config UI not updated immediately||||not started&lt;br /&gt;
|-&lt;br /&gt;
|When deleting attachments, the message list selection is lost||||not started&lt;br /&gt;
|-&lt;br /&gt;
|Arrow not drawn for toolbar actions which have more sub-actions, like &amp;quot;Check Mail&amp;quot;||Probably kdelibs bug||Reported [http://bugs.kde.org/show_bug.cgi?id=151697 here]&lt;br /&gt;
|-&lt;br /&gt;
|Startup wizard: Layout of the &amp;quot;check what the server supports&amp;quot; page wrong for long server names||||not started&lt;br /&gt;
|-&lt;br /&gt;
|Shortcut dialog: Tag and template actions are not shown||||not started&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Fancy header: Spam status bar image broken||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Missing icons||||Are reported [[Projects/Oxygen/Missing_Icons|here]]&lt;br /&gt;
|--style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Pressing some keys (se for me) in the folder select dialog causes it to freeze. Seems to be infinite repaint chain bug.||||can't reproduce anymore. Fixed?&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Closing composer: When asked to save as draft, message is NOT saved||Possible dataloss||seems fixed, can't reproduce anymore&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== KAddressbook ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Small description !! Additional comments !! Status&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Incorrect background color in right pane: gray background on white background||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|When editing a person, I got a crash in kabcore.cpp:681, addr.resource() is valid, but addr.resource()-&amp;gt;readOnly() points to bad memory.||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Cannot change the name of standard addressbook resource||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Cannot save addressbook for standard resource (std.vcf)|| reported by toma ||fixed&lt;br /&gt;
|-&lt;br /&gt;
|Crash when exiting kaddressbook after editing contact.||d-&amp;gt;mManager is 0 in kdepimlibs/kabc/addressbook.cpp:443||not started&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Crash when changing settings||DBUS message caused crash. I have uncommented it for now. Could it be removed? (s. kcmconfigs/addresseewidget.cpp:205||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Crash when resizing main window and jump button bar is enabled||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Status of checkboxes is not saved in KPIM::AddresseeView||in kdepim/libkdepim/addresseeview.cpp||worksforme&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== KNode ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Small description !! Additional comments !! Status&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|New Account dialog: Redundant slider next to port settings||||fixed&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|New Account dialog: Silently drops settings if no account name was entered||Should use the server name if left empty||fixed (r739089)&lt;br /&gt;
|-&lt;br /&gt;
|Shortcuts (eg. v for View Source) do not work||||not started&lt;br /&gt;
|-style=&amp;quot;background:lightgreen&amp;quot;&lt;br /&gt;
|Wrong homepage in about dialog||Should be http://kontact.kde.org/knode/ instead of http://knode.sourceforge.net//||fixed&lt;br /&gt;
|-&lt;br /&gt;
|Missing icons in folder list, menus, and configure dialog||Some of these might already exist for KMail, else see http://techbase.kde.org/Projects/Oxygen/Missing_Icons||not started&lt;br /&gt;
|-&lt;br /&gt;
|Too many items in toolbar||With the captions, the toolbar spans two rows, even on 1280x1024||not started&lt;br /&gt;
|-&lt;br /&gt;
|Splitter position between message display and message list not restored correctly||||not started&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:PIM]]&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Thread:Talk:Policies/Licensing_Policy/GFDL_1.2_is_listed_twice</id>
		<title>Thread:Talk:Policies/Licensing Policy/GFDL 1.2 is listed twice</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Thread:Talk:Policies/Licensing_Policy/GFDL_1.2_is_listed_twice"/>
				<updated>2012-01-27T19:26:33Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: they differ only in KDE approval&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There are two identical bullets in §8 describing [[GFDL]] 1.2, they differ only in [[KDE]] approval.  Why is that?  Is it a way of legally saying that unapproved licenses are allowed?&lt;br /&gt;
&lt;br /&gt;
Should it be assumed that documentation that bears no licensing metadata is [[GFDL]]?&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Thread:Talk:Policies/Licensing_Policy/GFDL_1.2_is_listed_twice</id>
		<title>Thread:Talk:Policies/Licensing Policy/GFDL 1.2 is listed twice</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Thread:Talk:Policies/Licensing_Policy/GFDL_1.2_is_listed_twice"/>
				<updated>2012-01-25T12:25:30Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: New thread: GFDL 1.2 is listed twice&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There are two identical bullets in §8 describing GFDL 1.2, they differ only in letter spacing.  Why is that?&lt;br /&gt;
&lt;br /&gt;
Should it be assumed that documentation that bears no licensing metadata is GFDL?&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Help:Contents</id>
		<title>Help:Contents</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Help:Contents"/>
				<updated>2011-03-26T22:22:16Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Wiki Syntax */ link titles&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Help:Contents}}&lt;br /&gt;
&lt;br /&gt;
Before you start to add or change content, please read:&lt;br /&gt;
* [[Help:Contribute|Contributing to TechBase]]&lt;br /&gt;
* [[Help:Wiki Structure|Wiki Structure]]&lt;br /&gt;
* [[Help:Wiki Translation|Translation into other Languages]]&lt;br /&gt;
* [[KDE_TechBase:Migrate_content|Migrating Content]]&lt;br /&gt;
* [[KDE_TechBase:Contributors|List of active contributors]], also contact points&lt;br /&gt;
&lt;br /&gt;
== Wiki Syntax ==&lt;br /&gt;
To get started with the MediaWiki syntax, read:&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Help:Editing Help on Editing]&lt;br /&gt;
* [http://meta.wikimedia.org/wiki/Help:Table Wikitables]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Wikipedia:Extended_image_syntax Syntax for displaying images]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Help:Magic_words Magic words]&lt;br /&gt;
&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Wikipedia:Cheatsheet The most important commands]&lt;br /&gt;
* How to [[KDE TechBase:Migrate content|Migrate content]]&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
; Syntax highlighting&lt;br /&gt;
: Wrap your C++ Qt/KDE code snippets in &amp;lt;TT &amp;gt;&amp;amp;lt;code cpp&amp;amp;gt;&amp;lt;/TT &amp;gt;, &amp;lt;TT &amp;gt;&amp;amp;lt;code cpp n&amp;amp;gt;&amp;lt;/TT &amp;gt;, &amp;lt;TT &amp;gt;&amp;amp;lt;code cpp-qt&amp;amp;gt;&amp;lt;/TT &amp;gt; and &amp;lt;TT &amp;gt;&amp;amp;lt;/code&amp;amp;gt;&amp;lt;/TT &amp;gt; to get syntax highlighting (&amp;lt;TT &amp;gt;cpp&amp;lt;/TT &amp;gt; for C++, &amp;lt;TT &amp;gt;cpp-qt&amp;lt;/TT &amp;gt; for Qt) and numbered lines (&amp;lt;TT &amp;gt;n&amp;lt;/TT &amp;gt;). Replace &amp;lt;TT &amp;gt;cpp&amp;lt;/TT &amp;gt; with [http://www.mediawiki.org/wiki/Extension:SyntaxHighlight_GeSHi#Supported_languages the language used], e.g. &amp;lt;TT &amp;gt;ruby&amp;lt;/TT &amp;gt; for Ruby and &amp;lt;TT &amp;gt;python&amp;lt;/TT &amp;gt; for Python (soon). Use &amp;lt;TT &amp;gt;ini&amp;lt;/TT &amp;gt; for {{path|.desktop}} files, &amp;lt;TT &amp;gt;xml&amp;lt;/TT &amp;gt; for XML files.  Use plain &amp;lt;TT &amp;gt;&amp;amp;lt;code&amp;gt;&amp;lt;/TT &amp;gt; for wikitext (for now).&lt;br /&gt;
&lt;br /&gt;
== New Templates ==&lt;br /&gt;
To get a list of pages using a template, go to corresponding template page (e.g. [[Template:movepage]]) and click &amp;quot;''What links here''&amp;quot; in the toolbox.&lt;br /&gt;
&lt;br /&gt;
; [[Template:movepage|&amp;lt;nowiki&amp;gt;{{movepage|url}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to mark a page as not finished.&lt;br /&gt;
&lt;br /&gt;
; [[Template:Improve|&amp;lt;nowiki&amp;gt;{{improve|explanation}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Pages which need cleanups or contain empty sections and/or todos are marked with this template. Add an explanation if you want (optional)&lt;br /&gt;
&lt;br /&gt;
; [[Template:tip|&amp;lt;nowiki&amp;gt;{{tip|text}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to add a tip for the reader.&lt;br /&gt;
&lt;br /&gt;
; [[Template:note|&amp;lt;nowiki&amp;gt;{{note|text}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to add an explanatory note.&lt;br /&gt;
&lt;br /&gt;
; [[Template:warning|&amp;lt;nowiki&amp;gt;{{warning|text}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to add a warning.&lt;br /&gt;
&lt;br /&gt;
; [[Template:qt|&amp;lt;nowiki&amp;gt;{{qt|class-name}}&amp;lt;/nowiki&amp;gt;]] and [[Template:qt3|&amp;lt;nowiki&amp;gt;{{qt3|class-name}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to generate a link to a Qt class, e.g. QWidget. For Qt3 classes use &amp;lt;nowiki&amp;gt;{{qt3|class-name}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; [[Template:class|&amp;lt;nowiki&amp;gt;{{class|class-name}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to generate a link to a KDE class, e.g. KDialog.&lt;br /&gt;
&lt;br /&gt;
; [[Template:path|&amp;lt;nowiki&amp;gt;{{path|path-or-filename}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template for paths and filenames, this way all of them have a consistent style.&lt;br /&gt;
&lt;br /&gt;
; [[Template:bug|&amp;lt;nowiki&amp;gt;{{bug|123456}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to automatically create a link to KDE's bugzilla.&lt;br /&gt;
&lt;br /&gt;
; [[Template:KDE3|&amp;lt;nowiki&amp;gt;{{KDE3}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to mark the content of a page as applicable for either KDE 3. Don't tag technology agnostic pages. For KDE4 content, use &amp;lt;nowiki&amp;gt;[[Category:KDE4]]&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
; [[Template:TutorialBrowser|&amp;lt;nowiki&amp;gt;{{TutorialBrowser|series|name|pre|next|reading}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: A template for tutorial navigation&lt;br /&gt;
&lt;br /&gt;
; [[Template:Box|&amp;lt;nowiki&amp;gt;{{Box|caption|text|width|float}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to create a box with a caption and a text. The width parameter is optional and can be specified absolute (400px) or relative (50%). The last parameter is the float value, which is also optional and defaults to center.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Help:Contents</id>
		<title>Help:Contents</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Help:Contents"/>
				<updated>2011-03-26T22:14:25Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: better link titles&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Help:Contents}}&lt;br /&gt;
&lt;br /&gt;
Before you start to add or change content, please read:&lt;br /&gt;
* [[Help:Contribute|Contributing to TechBase]]&lt;br /&gt;
* [[Help:Wiki Structure|Wiki Structure]]&lt;br /&gt;
* [[Help:Wiki Translation|Translation into other Languages]]&lt;br /&gt;
* [[KDE_TechBase:Migrate_content|Migrating Content]]&lt;br /&gt;
* [[KDE_TechBase:Contributors|List of active contributors]], also contact points&lt;br /&gt;
&lt;br /&gt;
== Wiki Syntax ==&lt;br /&gt;
To get started with the MediaWiki syntax, read:&lt;br /&gt;
* http://en.wikipedia.org/wiki/Help:Editing &lt;br /&gt;
* http://meta.wikimedia.org/wiki/Help:Table&lt;br /&gt;
* http://en.wikipedia.org/wiki/Wikipedia:Extended_image_syntax&lt;br /&gt;
* http://en.wikipedia.org/wiki/Help:Magic_words&lt;br /&gt;
&lt;br /&gt;
[The most important commands are summarized in the [http://en.wikipedia.org/wiki/Wikipedia:Cheatsheet Wikipedia Cheatsheet]. Information about how to migrate content [KDE TechBase:Migrate_content|can be found here].&lt;br /&gt;
]&lt;br /&gt;
--[[User:OpenIDUser83|OpenIDUser83]] 11:15, 1 March 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
; Syntax highlighting&lt;br /&gt;
: Wrap your C++ Qt/KDE code snippets in &amp;lt;TT &amp;gt;&amp;amp;lt;code cpp&amp;amp;gt;&amp;lt;/TT &amp;gt;, &amp;lt;TT &amp;gt;&amp;amp;lt;code cpp n&amp;amp;gt;&amp;lt;/TT &amp;gt;, &amp;lt;TT &amp;gt;&amp;amp;lt;code cpp-qt&amp;amp;gt;&amp;lt;/TT &amp;gt; and &amp;lt;TT &amp;gt;&amp;amp;lt;/code&amp;amp;gt;&amp;lt;/TT &amp;gt; to get syntax highlighting (&amp;lt;TT &amp;gt;cpp&amp;lt;/TT &amp;gt; for C++, &amp;lt;TT &amp;gt;cpp-qt&amp;lt;/TT &amp;gt; for Qt) and numbered lines (&amp;lt;TT &amp;gt;n&amp;lt;/TT &amp;gt;). Replace &amp;lt;TT &amp;gt;cpp&amp;lt;/TT &amp;gt; with [http://www.mediawiki.org/wiki/Extension:SyntaxHighlight_GeSHi#Supported_languages the language used], e.g. &amp;lt;TT &amp;gt;ruby&amp;lt;/TT &amp;gt; for Ruby and &amp;lt;TT &amp;gt;python&amp;lt;/TT &amp;gt; for Python (soon). Use &amp;lt;TT &amp;gt;ini&amp;lt;/TT &amp;gt; for {{path|.desktop}} files, &amp;lt;TT &amp;gt;xml&amp;lt;/TT &amp;gt; for XML files.  Use plain &amp;lt;TT &amp;gt;&amp;amp;lt;code&amp;gt;&amp;lt;/TT &amp;gt; for wikitext (for now).&lt;br /&gt;
&lt;br /&gt;
== New Templates ==&lt;br /&gt;
To get a list of pages using a template, go to corresponding template page (e.g. [[Template:movepage]]) and click &amp;quot;''What links here''&amp;quot; in the toolbox.&lt;br /&gt;
&lt;br /&gt;
; [[Template:movepage|&amp;lt;nowiki&amp;gt;{{movepage|url}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to mark a page as not finished.&lt;br /&gt;
&lt;br /&gt;
; [[Template:Improve|&amp;lt;nowiki&amp;gt;{{improve|explanation}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Pages which need cleanups or contain empty sections and/or todos are marked with this template. Add an explanation if you want (optional)&lt;br /&gt;
&lt;br /&gt;
; [[Template:tip|&amp;lt;nowiki&amp;gt;{{tip|text}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to add a tip for the reader.&lt;br /&gt;
&lt;br /&gt;
; [[Template:note|&amp;lt;nowiki&amp;gt;{{note|text}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to add an explanatory note.&lt;br /&gt;
&lt;br /&gt;
; [[Template:warning|&amp;lt;nowiki&amp;gt;{{warning|text}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to add a warning.&lt;br /&gt;
&lt;br /&gt;
; [[Template:qt|&amp;lt;nowiki&amp;gt;{{qt|class-name}}&amp;lt;/nowiki&amp;gt;]] and [[Template:qt3|&amp;lt;nowiki&amp;gt;{{qt3|class-name}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to generate a link to a Qt class, e.g. QWidget. For Qt3 classes use &amp;lt;nowiki&amp;gt;{{qt3|class-name}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; [[Template:class|&amp;lt;nowiki&amp;gt;{{class|class-name}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to generate a link to a KDE class, e.g. KDialog.&lt;br /&gt;
&lt;br /&gt;
; [[Template:path|&amp;lt;nowiki&amp;gt;{{path|path-or-filename}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template for paths and filenames, this way all of them have a consistent style.&lt;br /&gt;
&lt;br /&gt;
; [[Template:bug|&amp;lt;nowiki&amp;gt;{{bug|123456}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to automatically create a link to KDE's bugzilla.&lt;br /&gt;
&lt;br /&gt;
; [[Template:KDE3|&amp;lt;nowiki&amp;gt;{{KDE3}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to mark the content of a page as applicable for either KDE 3. Don't tag technology agnostic pages. For KDE4 content, use &amp;lt;nowiki&amp;gt;[[Category:KDE4]]&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
; [[Template:TutorialBrowser|&amp;lt;nowiki&amp;gt;{{TutorialBrowser|series|name|pre|next|reading}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: A template for tutorial navigation&lt;br /&gt;
&lt;br /&gt;
; [[Template:Box|&amp;lt;nowiki&amp;gt;{{Box|caption|text|width|float}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to create a box with a caption and a text. The width parameter is optional and can be specified absolute (400px) or relative (50%). The last parameter is the float value, which is also optional and defaults to center.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Help:Contents</id>
		<title>Help:Contents</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Help:Contents"/>
				<updated>2011-03-26T22:12:30Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: style&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Help:Contents}}&lt;br /&gt;
&lt;br /&gt;
Before you start to add or change content, please read:&lt;br /&gt;
* [[Help:Contribute|Contribute to TechBase]]&lt;br /&gt;
* [[Help:Wiki Structure|Wiki Structure]]&lt;br /&gt;
* [[Help:Wiki Translation|Translation into other Languages]]&lt;br /&gt;
* [[KDE_TechBase:Migrate_content|Migrate Content]]&lt;br /&gt;
* [[KDE_TechBase:Contributors|List of active contributors]], also contact points&lt;br /&gt;
&lt;br /&gt;
== Wiki Syntax ==&lt;br /&gt;
To get started with the MediaWiki syntax, read:&lt;br /&gt;
* http://en.wikipedia.org/wiki/Help:Editing&lt;br /&gt;
* http://meta.wikimedia.org/wiki/Help:Table&lt;br /&gt;
* http://en.wikipedia.org/wiki/Wikipedia:Extended_image_syntax&lt;br /&gt;
* http://en.wikipedia.org/wiki/Help:Magic_words&lt;br /&gt;
&lt;br /&gt;
[The most important commands are summarized in the [http://en.wikipedia.org/wiki/Wikipedia:Cheatsheet Wikipedia Cheatsheet]. Information about how to migrate content [KDE TechBase:Migrate_content|can be found here].&lt;br /&gt;
]&lt;br /&gt;
--[[User:OpenIDUser83|OpenIDUser83]] 11:15, 1 March 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
; Syntax highlighting&lt;br /&gt;
: Wrap your C++ Qt/KDE code snippets in &amp;lt;TT &amp;gt;&amp;amp;lt;code cpp&amp;amp;gt;&amp;lt;/TT &amp;gt;, &amp;lt;TT &amp;gt;&amp;amp;lt;code cpp n&amp;amp;gt;&amp;lt;/TT &amp;gt;, &amp;lt;TT &amp;gt;&amp;amp;lt;code cpp-qt&amp;amp;gt;&amp;lt;/TT &amp;gt; and &amp;lt;TT &amp;gt;&amp;amp;lt;/code&amp;amp;gt;&amp;lt;/TT &amp;gt; to get syntax highlighting (&amp;lt;TT &amp;gt;cpp&amp;lt;/TT &amp;gt; for C++, &amp;lt;TT &amp;gt;cpp-qt&amp;lt;/TT &amp;gt; for Qt) and numbered lines (&amp;lt;TT &amp;gt;n&amp;lt;/TT &amp;gt;). Replace &amp;lt;TT &amp;gt;cpp&amp;lt;/TT &amp;gt; with [http://www.mediawiki.org/wiki/Extension:SyntaxHighlight_GeSHi#Supported_languages the language used], e.g. &amp;lt;TT &amp;gt;ruby&amp;lt;/TT &amp;gt; for Ruby and &amp;lt;TT &amp;gt;python&amp;lt;/TT &amp;gt; for Python (soon). Use &amp;lt;TT &amp;gt;ini&amp;lt;/TT &amp;gt; for {{path|.desktop}} files, &amp;lt;TT &amp;gt;xml&amp;lt;/TT &amp;gt; for XML files.  Use plain &amp;lt;TT &amp;gt;&amp;amp;lt;code&amp;gt;&amp;lt;/TT &amp;gt; for wikitext (for now).&lt;br /&gt;
&lt;br /&gt;
== New Templates ==&lt;br /&gt;
To get a list of pages using a template, go to corresponding template page (e.g. [[Template:movepage]]) and click &amp;quot;''What links here''&amp;quot; in the toolbox.&lt;br /&gt;
&lt;br /&gt;
; [[Template:movepage|&amp;lt;nowiki&amp;gt;{{movepage|url}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to mark a page as not finished.&lt;br /&gt;
&lt;br /&gt;
; [[Template:Improve|&amp;lt;nowiki&amp;gt;{{improve|explanation}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Pages which need cleanups or contain empty sections and/or todos are marked with this template. Add an explanation if you want (optional)&lt;br /&gt;
&lt;br /&gt;
; [[Template:tip|&amp;lt;nowiki&amp;gt;{{tip|text}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to add a tip for the reader.&lt;br /&gt;
&lt;br /&gt;
; [[Template:note|&amp;lt;nowiki&amp;gt;{{note|text}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to add an explanatory note.&lt;br /&gt;
&lt;br /&gt;
; [[Template:warning|&amp;lt;nowiki&amp;gt;{{warning|text}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to add a warning.&lt;br /&gt;
&lt;br /&gt;
; [[Template:qt|&amp;lt;nowiki&amp;gt;{{qt|class-name}}&amp;lt;/nowiki&amp;gt;]] and [[Template:qt3|&amp;lt;nowiki&amp;gt;{{qt3|class-name}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to generate a link to a Qt class, e.g. QWidget. For Qt3 classes use &amp;lt;nowiki&amp;gt;{{qt3|class-name}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; [[Template:class|&amp;lt;nowiki&amp;gt;{{class|class-name}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to generate a link to a KDE class, e.g. KDialog.&lt;br /&gt;
&lt;br /&gt;
; [[Template:path|&amp;lt;nowiki&amp;gt;{{path|path-or-filename}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template for paths and filenames, this way all of them have a consistent style.&lt;br /&gt;
&lt;br /&gt;
; [[Template:bug|&amp;lt;nowiki&amp;gt;{{bug|123456}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to automatically create a link to KDE's bugzilla.&lt;br /&gt;
&lt;br /&gt;
; [[Template:KDE3|&amp;lt;nowiki&amp;gt;{{KDE3}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to mark the content of a page as applicable for either KDE 3. Don't tag technology agnostic pages. For KDE4 content, use &amp;lt;nowiki&amp;gt;[[Category:KDE4]]&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
; [[Template:TutorialBrowser|&amp;lt;nowiki&amp;gt;{{TutorialBrowser|series|name|pre|next|reading}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: A template for tutorial navigation&lt;br /&gt;
&lt;br /&gt;
; [[Template:Box|&amp;lt;nowiki&amp;gt;{{Box|caption|text|width|float}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to create a box with a caption and a text. The width parameter is optional and can be specified absolute (400px) or relative (50%). The last parameter is the float value, which is also optional and defaults to center.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Services/Traders</id>
		<title>Development/Tutorials/Services/Traders</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Services/Traders"/>
				<updated>2010-11-30T10:39:45Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* String Matching Operators */ ktraderclient&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Tutorials/Services/Traders}}&lt;br /&gt;
&lt;br /&gt;
{{TutorialBrowser|&lt;br /&gt;
&lt;br /&gt;
series=Services|&lt;br /&gt;
&lt;br /&gt;
name=Finding Services Using Trader Queries|&lt;br /&gt;
&lt;br /&gt;
pre=[[../Introduction|Introduction to the Services Framework]]|&lt;br /&gt;
&lt;br /&gt;
next=[[../Plugins|Creating and Loading Plugins Using KService]]|&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
It is often desirable to be able to find specific types of services or services with specific features or designations. KDE provides a simple yet powerful query language to accomplish this called the KTrader Query Language.&lt;br /&gt;
&lt;br /&gt;
== A Tale of Two Traders ==&lt;br /&gt;
&lt;br /&gt;
KDE provides two classes that act as &amp;quot;traders&amp;quot;. A trader takes a query and returns a set of services that match those constraints. There is one trader for plugins and other add-ons: {{class|KServiceTypeTrader}}, and one for mimetypes: {{class|KMimetypeTrader}}. Characteristics for both are similar: they have same syntax for querying, offer a singleton pattern accessor, return {{class|KService}}::Ptrs, as well as other similarities. So while this tutorial concentrates primarily on the {{class|KServiceTypeTrader}}, much of the content is applicable to the mimetype trader as well.&lt;br /&gt;
&lt;br /&gt;
== Service Types ==&lt;br /&gt;
&lt;br /&gt;
{{class|KServiceTypeTrader}} is used to locate individual components such as application plugins, screensavers, and control panels that are registered with the system. The primary concept used here, is that of the &amp;quot;service type&amp;quot;. Each set of services has a unique service type, which makes it very easy to locate the sort of component needed.&lt;br /&gt;
&lt;br /&gt;
This means that, each kind of application plugin is uniquely namespaced within the set of all services. So, it is trivial to locate plugins for a given application, without having to worry about getting another application's plugin in the list.&lt;br /&gt;
&lt;br /&gt;
Examples of service types include:&lt;br /&gt;
*KParts/ReadWritePart&lt;br /&gt;
*KTextEditor/Document&lt;br /&gt;
*ScreenSaver&lt;br /&gt;
*TerminalEmulator&lt;br /&gt;
*UserAgentStrings&lt;br /&gt;
*ThumbCreator&lt;br /&gt;
*KDevelop/Plugin&lt;br /&gt;
&lt;br /&gt;
There is no limit to the number of service types that a given application may use or register. Of course, service types are not limited to plugins and may be used for any sort of data component. &lt;br /&gt;
&lt;br /&gt;
Creating new service types is covered in the next tutorial of this series:&lt;br /&gt;
[[Development/Tutorials/Services/Plugins|Creating and Loading Plugins Using KService]]&lt;br /&gt;
&lt;br /&gt;
== Basic KServiceTypeTrader Usage ==&lt;br /&gt;
&lt;br /&gt;
The service trader is always accessed via the &amp;lt;tt&amp;gt;self()&amp;lt;/tt&amp;gt; singleton accessor. With the {{class|KServiceTypeTrader}} in hand, we can then do one of three things:&lt;br /&gt;
*'''query''': query for a list of services ordered according to the user's preferences (if any)&lt;br /&gt;
*'''defaultOffers''': request all services, unsorted&lt;br /&gt;
*'''preferredService''': request the preferred service of a given type&lt;br /&gt;
&lt;br /&gt;
The code to do this is very straight forward:&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;&lt;br /&gt;
KService::List services;&lt;br /&gt;
KServiceTypeTrader* trader = KServiceTypeTrader::self();&lt;br /&gt;
&lt;br /&gt;
services = trader-&amp;gt;query(&amp;quot;KParts/ReadWritePart&amp;quot;);&lt;br /&gt;
foreach (KService::Ptr service, services) {&lt;br /&gt;
    kDebug() &amp;lt;&amp;lt; &amp;quot;read write part&amp;quot; &amp;lt;&amp;lt; service-&amp;gt;name();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
services = trader-&amp;gt;defaultOffers(&amp;quot;ThumbCreator&amp;quot;);&lt;br /&gt;
if (services.isEmpty()) {&lt;br /&gt;
    kDebug() &amp;lt;&amp;lt; &amp;quot;no services found for ThumbCreator!&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
KService::Ptr service = trader-&amp;gt;preferredService(&amp;quot;KDevelop/Plugin&amp;quot;);&lt;br /&gt;
if (!service) {&lt;br /&gt;
    kDebug() &amp;lt;&amp;lt; &amp;quot;no preferred service found for KDevelop/Plugin&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In each case zero or more services are returned that are now usable for locating, describing and loading the item it represents.&lt;br /&gt;
&lt;br /&gt;
== The KTrader Query Language ==&lt;br /&gt;
&lt;br /&gt;
The above examples are quite simplistic and are not detailed enough for many application needs. For instance, we may only want to list plugins for a certain category, that are associated with a particular mimetype, or that have a specific plugin name. This is where the query language comes in.&lt;br /&gt;
&lt;br /&gt;
The query language itself is designed to be human readable and flexible. &amp;lt;tt&amp;gt;{{class|KServiceTypeTrader}}::query&amp;lt;/tt&amp;gt; optionally takes a query, in addition to the service type, and uses that to provide more fine-grained searches. So, for example, we'll modify the earlier example in the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;&lt;br /&gt;
KService::List services ;&lt;br /&gt;
KServiceTypeTrader* trader = KServiceTypeTrader::self();&lt;br /&gt;
&lt;br /&gt;
QString constraint = &amp;quot;'text/plain' in MimeTypes and &amp;quot;&lt;br /&gt;
                     &amp;quot;('KOfficePart' in ServiceTypes or &amp;quot;&lt;br /&gt;
                     &amp;quot; 'oasis' ~ [X-KDE-ExtraNativeMimeTypes])&amp;quot;;&lt;br /&gt;
services = trader-&amp;gt;query(&amp;quot;KParts/ReadWritePart&amp;quot;, constraint);&lt;br /&gt;
&lt;br /&gt;
foreach (KService::Ptr service, services) {&lt;br /&gt;
    kDebug() &amp;lt;&amp;lt; &amp;quot;read write part&amp;quot; &amp;lt;&amp;lt; service-&amp;gt;name();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code will look for a KPart that is both capable of reading/writing plain text files and is also a KOffice component, or can simply read ODF document formats.&lt;br /&gt;
&lt;br /&gt;
Errors in queries are reported via debug output to console at runtime.&lt;br /&gt;
&lt;br /&gt;
=== Order of Operations ===&lt;br /&gt;
&lt;br /&gt;
The query string is evaluated left to right, one section at a time. Sections are divided by boolean operators (see below) or by parentheses ('()'), which serve as grouping characters.&lt;br /&gt;
&lt;br /&gt;
=== Literals ===&lt;br /&gt;
&lt;br /&gt;
Three types of literals are supported by the KTrader Query Language:&lt;br /&gt;
*'''strings''': character strings, which must be enclosed in single quotes (')&lt;br /&gt;
*'''booleans''': TRUE or FALSE&lt;br /&gt;
*'''signed integers'''&lt;br /&gt;
*'''signed floating point numbers'''&lt;br /&gt;
&lt;br /&gt;
=== Identifiers ===&lt;br /&gt;
 &lt;br /&gt;
Identifiers in a query string are mapped to entries listed in the service's &amp;lt;tt&amp;gt;.desktop&amp;lt;/tt&amp;gt; file. For example, &amp;quot;Name&amp;quot; is the name of the service, &amp;quot;ServiceTypes&amp;quot; is a list of the service types it supports. &lt;br /&gt;
&lt;br /&gt;
Identifiers may only contain alphanumeric characters and the '-' character.&lt;br /&gt;
Identifiers that do not start with an alphabetical character or that contain non-alphanumeric characters must be enclosed in brackets, e.g. [X-KDE-Init]. &lt;br /&gt;
&lt;br /&gt;
There are also three special identifiers:&lt;br /&gt;
&lt;br /&gt;
*'''DesktopEntryName''' stands for the filename of the service desktop entry without its extension. This can be useful to exclude some specific services.&lt;br /&gt;
*'''DesktopEntryPath''' stands for the relative or full path to the .desktop file, see {{class|KService}}::desktopEntryPath.&lt;br /&gt;
*'''Library''': a synonym for [X-KDE-Library] in the .desktop file.&lt;br /&gt;
&lt;br /&gt;
An identifier can be checked for existence with the '''exist''' operator, e.g. &amp;quot;exist [X-KDE-Library]&amp;quot;. This is especially useful when checking for the value of an identifier with a default value. For example, if MyProp is a property with type boolean, one might write &amp;quot;not exist MyProp or MyProp&amp;quot; to match MyProp with a default of &amp;quot;true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;&lt;br /&gt;
QString term = &amp;quot;konq&amp;quot;;&lt;br /&gt;
QString query = QString(&amp;quot;exist Exec and ((exist Keywords and '%1' ~subin Keywords) or (exist GenericName and '%1' ~~ GenericName) or (exist Name and '%1' ~~ Name))&amp;quot;).arg(term);&lt;br /&gt;
KService::List services = KServiceTypeTrader::self()-&amp;gt;query(&amp;quot;Application&amp;quot;, query);&lt;br /&gt;
foreach (KService::Ptr service, services) {&lt;br /&gt;
    kDebug() &amp;lt;&amp;lt; service-&amp;gt;name();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comparison Operators ===&lt;br /&gt;
&lt;br /&gt;
The following comparison operators can be used to compare values of any of the supported data types:&lt;br /&gt;
&lt;br /&gt;
*'''==''': equality&lt;br /&gt;
*'''!=''': inequality&lt;br /&gt;
*'''&amp;lt;''': less than&lt;br /&gt;
*'''&amp;lt;=''': less than or equal to&lt;br /&gt;
*'''&amp;gt;''': greater than&lt;br /&gt;
*'''&amp;gt;=''': greater than or equal to&lt;br /&gt;
&lt;br /&gt;
=== Mathematical Operators ===&lt;br /&gt;
&lt;br /&gt;
The following mathematical operators can be used with numerical types:&lt;br /&gt;
&lt;br /&gt;
* '''+'''&lt;br /&gt;
* '''-'''&lt;br /&gt;
* '''*'''&lt;br /&gt;
* '''/'''&lt;br /&gt;
&lt;br /&gt;
=== Boolean Operators ===&lt;br /&gt;
&lt;br /&gt;
The following boolean operators are supported:&lt;br /&gt;
&lt;br /&gt;
* '''and'''&lt;br /&gt;
* '''or'''&lt;br /&gt;
* '''not'''&lt;br /&gt;
&lt;br /&gt;
=== String Matching Operators ===&lt;br /&gt;
&lt;br /&gt;
The string matching operators all return a boolean value, indicating success or failure.&lt;br /&gt;
&lt;br /&gt;
String comparisons are done using the following operators:&lt;br /&gt;
&lt;br /&gt;
*'''==''': equality, case sensitive&lt;br /&gt;
*'''=~''': equality, case insensitive&lt;br /&gt;
*'''!=''': inequality, case sensitive&lt;br /&gt;
*'''!~''': inequality, case insensitive&lt;br /&gt;
&lt;br /&gt;
Sub-string matching can be accomplished by using the following operators:&lt;br /&gt;
&lt;br /&gt;
* '''~''': contains, e.g. &amp;quot;'Bar' ~ 'FooBarBaz'&amp;quot; is true&lt;br /&gt;
* '''~~''': contains with case insensitive matching, e.g. &amp;quot;'Bar' ~~ 'FoobarBaz'&amp;quot; is true&lt;br /&gt;
&lt;br /&gt;
Some properties, such as MimeTypes and ServiceTypes, are lists of strings. These lists can be searched using the following operators:&lt;br /&gt;
&lt;br /&gt;
* '''in''': the list contains the string, e.g. &amp;quot;'MyApp/Plugin' in ServiceTypes'&amp;quot;&lt;br /&gt;
* '''~in''': the list contains the string, with case insensitive matching&lt;br /&gt;
* '''subin''': the list contains the string as a substring of one of the entries, e.g. &amp;quot;'Plugin' subin ServiceTypes'&amp;quot;&lt;br /&gt;
* '''~subin''': the list contains the string as a substring of one of the entries, with case insensitive matching&lt;br /&gt;
&lt;br /&gt;
== Command line tool ==&lt;br /&gt;
* ktraderclient --mimetype &amp;lt;var &amp;gt;mimetype&amp;lt;/var &amp;gt; --servicetype &amp;lt;var &amp;gt;servicetype&amp;lt;/var &amp;gt; --constraint &amp;lt;var &amp;gt;constraint&amp;lt;/var &amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy</id>
		<title>KDE System Administration/KDE Filesystem Hierarchy</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy"/>
				<updated>2010-11-30T10:19:39Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Directory Tree */ share/applications/&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|KDE_System_Administration/KDE_Filesystem_Hierarchy}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
KDE defines a filesystem hierarchy that is used by the KDE environment&lt;br /&gt;
itself as well as all KDE applications. In general, KDE stores all its&lt;br /&gt;
files in a fixed directory tree.&lt;br /&gt;
&lt;br /&gt;
By default, there are two such directory trees: one at the system&lt;br /&gt;
level and one at the user level in the user's home directory. However,&lt;br /&gt;
as a system administrator you can create additional trees.&lt;br /&gt;
&lt;br /&gt;
KDE and KDE applications look up files by scanning the directory trees&lt;br /&gt;
in order of precedence. When a file is&lt;br /&gt;
present in multiple directory trees, the file from the first-listed&lt;br /&gt;
tree takes precedence.&lt;br /&gt;
Normally, the tree located in the user's home directory has the highest&lt;br /&gt;
precedence. This is also the directory tree that changes are&lt;br /&gt;
written to.&lt;br /&gt;
&lt;br /&gt;
For configuration files, the story is slightly&lt;br /&gt;
different. If multiple configuration files with the same name are found in the directory&lt;br /&gt;
trees, their content is combined. The precedence order&lt;br /&gt;
of the directory trees plays a role here: when two files define the same&lt;br /&gt;
configuration key, the file with the highest precedence determines which&lt;br /&gt;
value is used for the key.&lt;br /&gt;
&lt;br /&gt;
== Location of the Directory Trees ==&lt;br /&gt;
&lt;br /&gt;
The location of the KDE Directory Trees is determined by a number of&lt;br /&gt;
environment variables, each of which is covered below.&lt;br /&gt;
&lt;br /&gt;
=== KDEHOME ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;KDEHOME&amp;lt;/tt&amp;gt; environment variable determines the location of the user-level&lt;br /&gt;
directory tree and is used by KDE applications for creating and saving&lt;br /&gt;
files. This directory tree has the highest precedence; files or settings&lt;br /&gt;
found in this directory tree will take precedence over any files or settings&lt;br /&gt;
found in other directory trees.&lt;br /&gt;
&lt;br /&gt;
This directory tree is, as the name suggests, normally located in the user's home directory. If this environment variable is not defined, the default location &amp;lt;tt&amp;gt;$HOME/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; is used.&lt;br /&gt;
&lt;br /&gt;
If the environment variable has a value that starts with a tilde (~), the tilde is replaced with the user's home directory at runtime. In order to use this, care must be taken to add proper quoting, otherwise the shell might do the expansion, resulting in undesired behavior in combination with &amp;lt;tt&amp;gt;su&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== KDEROOTHOME ===&lt;br /&gt;
In order to prevent problems with applications that run as root saving&lt;br /&gt;
files with root access permissions in the user's home directory, the &amp;lt;tt&amp;gt;KDEROOTHOME&amp;lt;/tt&amp;gt;&lt;br /&gt;
environment variable has been introduced in the KDE 3.x series. Applications&lt;br /&gt;
that run with uid 0 (root) will use this variable to determine the location of&lt;br /&gt;
the user level directory and where to save their files. If this variable is&lt;br /&gt;
not defined, the root user's home directory is looked up in the password&lt;br /&gt;
file and .kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt; is appended. Usually that results in &amp;lt;tt&amp;gt;/root/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== KDEDIRS ===&lt;br /&gt;
It is possible to specify multiple system-level directory trees. This allows groups of users to each dedicate a directory to their group. Such an additional directory tree can contain additional applications, specialized application resources or a specific set of default configurations suitable for the group. Specifying default configurations this way instead of using a /etc/skel construction has the advantage that changes in the default configuration can be made after the user's account has been created.&lt;br /&gt;
&lt;br /&gt;
The directories in $KDEDIRS should be separated with a colon (:). The directories are listed in order of precedence: the first directory has the highest precedence, the last one has the lowest precedence.&lt;br /&gt;
&lt;br /&gt;
Since a group-level directory tree should normally override any settings present at the system level, one should list the group-level directory tree before the system level directory tree.&lt;br /&gt;
&lt;br /&gt;
In general communication, references to the directory trees are made in&lt;br /&gt;
terms of $KDEHOME to indicate the applicable user-level directory tree,&lt;br /&gt;
and in terms of $KDEDIRS to indicate any of the system-level directory trees.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
A staff member at a university could have the following settings:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEROOTHOME='/root/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the user settings are saved under the .kde3 directory&lt;br /&gt;
in the user's home directory. Applications that run as root will save their&lt;br /&gt;
settings to /root/.kde3. KDE 3 has been installed to /opt/kde3 but there is&lt;br /&gt;
also an additional directory tree located at /opt/kde_staff. Configuration&lt;br /&gt;
files under that directory will take precedence over the ones in the /opt/kde3&lt;br /&gt;
system directories. /opt/kde_staff could contain additional applications that&lt;br /&gt;
should only be available to staff members.&lt;br /&gt;
&lt;br /&gt;
== Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
Each directory tree used by KDE has a fixed directory structure. However, directories&lt;br /&gt;
that are not relevant for a certain tree can be left out. For example,&lt;br /&gt;
directories used for temporary files are usually only found under $KDEHOME but&lt;br /&gt;
not in any other directory tree.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The KDE runtime environment combines the subdirectories found under the&lt;br /&gt;
various directory trees and refers to them as a single KDE resource. The&lt;br /&gt;
KDE resource name is listed in the tables below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are three broad categories: files that are&lt;br /&gt;
CPU/architecture-specific, files that are host-specific and files that are not specific with&lt;br /&gt;
regard to host, CPU or architecture.&lt;br /&gt;
&lt;br /&gt;
CPU/architecture-specific directories:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|bin/}} || exe || Used for KDE executables.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cgi-bin/}} || cgi || CGI scipts that can be used by the KDE Help Center.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || lib || Used for KDE libraries.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/kde&amp;lt;sub &amp;gt;3&amp;lt;var &amp;gt;&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || module || This directory contains components, plugins and other runtime loadable objects for use by KDE 3.x applications.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following are host-specific directories. They are only available under&lt;br /&gt;
$KDEHOME and are normally symlinked to locations outside the $KDEHOME&lt;br /&gt;
directory tree.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|socket-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Sockets|socket]] || This directory contains communication sockets. The filesystem used by $KDEHOME may not be suitable for communication sockets. For that reason this directory is symlinked to another location by default.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|tmp-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Temporary Files|tmp]] || This directory is used for temporary files. The filesystem used by $KDEHOME may be on a network, so, for performance reasons, this directory is symlinked by default to a location more likely to be on a local filesystem.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cache-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Cache Files|cache]] || New in KDE 3.2. This directory is used for cached information such as HTTP objects, formatted help pages and the system configuration cache (ksycoca).&lt;br /&gt;
&lt;br /&gt;
Since this is non-essential information, this directory is&lt;br /&gt;
symlinked to a location outside $KDEHOME by default to make it easier&lt;br /&gt;
to make backups of other information and reclaim diskspace.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The majority of directories involves data that is not CPU-, architecture- or&lt;br /&gt;
host-specific. All these directories are prefixed with {{path|share/}}:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/applnk/}} {{path|share/applications/}}|| apps || Contains .desktop files describing the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/apps/}} || data || Contains application-specific data files. Each application has a subdirectory here for storing its files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/}} || config || Contains configuration files. Configuration files are normally named after the application they belong to, followed by &amp;quot;rc&amp;quot;. There are also files that are specific to a component and as such referenced by all applications that use that component. A special case is &amp;quot;kdeglobals&amp;quot;: this file is read by all KDE applications.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/session/}} || - || This directory is used by session management and is normally only available under $KDEHOME. At the end of a session, KDE applications store their state here. The file names start with the name of the application followed by a number. The session manager &amp;quot;ksmserver&amp;quot; stores references to these numbers when saving a session in &amp;quot;ksmserverrc&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/doc/HTML/}} {{path|share/doc/kde/HTML/&amp;lt;var &amp;gt;lang&amp;lt;/var &amp;gt;/&amp;lt;var &amp;gt;package&amp;lt;/var &amp;gt;}}|| html || Documentation of KDE applications is stored here. Documentation is categorized by language and the application it belongs to. &lt;br /&gt;
&lt;br /&gt;
Normally, at least two files can be found in a directory: &amp;quot;index.docbook&amp;quot;, which contains the documentation in the unformatted docbook format, and &amp;quot;index.cache.bz2&amp;quot;, which contains the same documentation formatted as bzip2 compressed HTML. The HTML version is used by khelpcenter; if the HTML version is missing, it will regenerate it from the docbook version, but this is a time-consuming process.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/icons/}} || icon || Icons are stored under this directory, categorized by theme, dimension and usage category.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mimelnk/}} || mime || Up until KDE4, .desktop files that describe MIME types were stored in this directory.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mime/}} || mime || Starting with KDE4, desktop files that describe MIME types are stored in this directory. This data is shared by other software as well and is part of a freedesktop.org specification.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/services/}}&amp;lt;br&amp;gt;{{path|share/kde4/services/}} || services || This directory contains .desktop files that describe services. Services and Applications are very similar; the major difference is that a Service is usually used by other Services or Applications, while an Application is in general started by the user. Services do not appear in the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/servicetypes/}}&amp;lt;br&amp;gt;{{path|share/kde4/servicetypes/}} || servicetypes || This directory contains .desktop files that describe service types. A service type usually represents a certain programming interface. Applications and Services include the servicetypes that they provide in their .desktop files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/sounds/}} || sound || This directory contains sound files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/templates/}} || templates || This directory contains templates for creating files of various types. A template consists of a .desktop file that describes the file and includes a reference to a file in the .source subdirectory. The templates in this directory appear in the &amp;quot;Create New&amp;quot; menu available on the desktop and in the file browser. When a user selects a template from the menu, its source file is copied.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/wallpapers/}} || wallpaper || This directory contains images that can be used as background pictures.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Outside the Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
As mentioned in the description of the directory tree, there are three host-specific directories that are usually symlinked to other locations. If the directories do not already exist, the following symlinks and directories will be created using the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility. Since both &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt; are world writable, there is a possibility that one of the mentioned directories already exists but is owned by another user. In that case, the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility will create a new directory with an alternative name and link to that instead.&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/socket-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/ksocket-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
The command &amp;lt;tt&amp;gt;lnusertemp socket&amp;lt;/tt&amp;gt; creates a directory for local communication sockets and point a symlink to it. The combined length of the directory name and the name of any communication socket should not exceed 106 characters. By default this directory is created under &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt;, but other locations can be used by setting the KDETMP environment variable.&lt;br /&gt;
&lt;br /&gt;
=== Temporary Files ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/tmp-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/kde-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
The command &amp;lt;tt&amp;gt;lnusertemp tmp&amp;lt;/tt&amp;gt; creates a directory for temporary files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
=== Cache Files ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/cache-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
 &lt;br /&gt;
Default destination: {{path|/var/tmp/kdecache-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
The command &amp;lt;tt&amp;gt;lnusertemp cache&amp;lt;/tt&amp;gt; creates a directory for cache files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
The system configuration cache (&amp;lt;tt &amp;gt;ksycoca&amp;lt;/tt &amp;gt; and &amp;lt;tt &amp;gt;ksycocastamp&amp;lt;/tt &amp;gt;) is located in here. It is recommended NOT to delete these files during boot since that will slow down the startup of KDE.&lt;br /&gt;
&lt;br /&gt;
By default this directory is created under &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt;, other locations&lt;br /&gt;
can be used by setting the KDEVARTMP environment variable.&lt;br /&gt;
&lt;br /&gt;
== Adding Lookup Locations ==&lt;br /&gt;
&lt;br /&gt;
KDE applications look up data files using the resource names listed in the&lt;br /&gt;
[[#Directory Tree]] section.  The KDE runtime&lt;br /&gt;
environment translates these names to actual directories&lt;br /&gt;
by combining the locations of the directory trees with the directories&lt;br /&gt;
listed in the tables.&lt;br /&gt;
&lt;br /&gt;
==== Defining Search Paths ====&lt;br /&gt;
&lt;br /&gt;
A user has the following directory tree settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an application now looks for a &amp;quot;wallpaper&amp;quot; file, the directory {{path|share/wallpapers/}} is added to each of the&lt;br /&gt;
directory trees. All of the&lt;br /&gt;
resulting directories are then searched for the file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By adding more directory tree to the KDEDIRS environment variable&lt;br /&gt;
it is possible to expand the number of directories that are being searched.&lt;br /&gt;
Sometimes it is desirable to include only a single directory in a search&lt;br /&gt;
but not a whole directory tree. Additional directories can be configured&lt;br /&gt;
in the &amp;lt;TT &amp;gt;kdeglobals&amp;lt;/TT &amp;gt; configuration file in the &amp;lt;TT &amp;gt;[Directories]&amp;lt;/TT &amp;gt; section.&lt;br /&gt;
To do so assign one or more directories to the key &amp;lt;TT &amp;gt;dir_&amp;lt;/TT &amp;gt; followed by the&lt;br /&gt;
name of the resource. &lt;br /&gt;
Multiple directories are separated by commas (&amp;lt;TT &amp;gt;,&amp;lt;/TT &amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==== Adding a Resource Directory ====&lt;br /&gt;
&lt;br /&gt;
To add the directory {{path|/data/photos}} to the wallpaper resource, put the&lt;br /&gt;
following two lines in &amp;lt;TT &amp;gt;kdeglobals&amp;lt;/TT &amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Directories]&lt;br /&gt;
dir_wallpaper=/data/photos&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the application now looks for wallpaper files, it will look in the&lt;br /&gt;
following locations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
/data/photos&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions</id>
		<title>Development/Tutorials/Solid/Device Actions</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions"/>
				<updated>2010-09-15T21:34:17Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Installing actions */ where is above&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The '''Device Notifier''' is a plasmoid that is responsible for handling device events.  When new data device is inserted or detected by '''Solid''', it gets added to the Device Notifier menu.  Each device has a set of ''actions'' the user can perform on the device, depending on the device type and its contents.  For example, when the media is an audio CD, the Device Notifier offers you to play that CD using '''Amarok'''.  The default actions are not a part of '''Plasma'''; rather, each one is installed by the application that handles the action, and goes away when the application is removed.&lt;br /&gt;
&lt;br /&gt;
You can add your own actions and modify existing ones using the '''Device Actions''' system setting module; however, such changes are limited to the user that requests the change.  If you want to install a custom action along with your application, you have to dig a bit deeper.&lt;br /&gt;
&lt;br /&gt;
== Anatomy of an action ==&lt;br /&gt;
&lt;br /&gt;
An Action file is a desktop configuration file similar to the following one:&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Desktop Entry]&lt;br /&gt;
X-KDE-Solid-Predicate=OpticalDisc.availableContent &amp;amp; 'Audio'&lt;br /&gt;
Type=Service&lt;br /&gt;
Actions=Play;&lt;br /&gt;
&lt;br /&gt;
[Desktop Action Play]&lt;br /&gt;
Name=Play Audio CD with Amarok&lt;br /&gt;
Name[fr]=Jouer CD Audio avec Amarok&lt;br /&gt;
# names in other languages&lt;br /&gt;
Icon=amarok&lt;br /&gt;
Exec=amarok --cdplay %f&lt;br /&gt;
&amp;lt;/code &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Actions and devices ==&lt;br /&gt;
&lt;br /&gt;
The '''Device Notifier''' gets the devices and their corresponding actions by interrogating its data engine called '''hotplug'''.  The '''hotplug''' data engine gets the set of devices from '''Solid''' and the set of actions from the subdirectories {{path|./solid/actions}} relative to the application settings path in '''KDE'''.  The set of actions pertaining to each device is then obtained by evaluating the Solid Predicate specified in the action against the physical and logical properties of the device; if the predicate holds, the action is included.&lt;br /&gt;
&lt;br /&gt;
== Action predicates ==&lt;br /&gt;
The predicate for each action is specified in the entry &amp;lt;TT &amp;gt;X-KDE-Solid-Predicate&amp;lt;/TT &amp;gt;.  The syntax of the predicate allows to construct an object of class '''Solid::Predicate''' out of it.&lt;br /&gt;
&lt;br /&gt;
Atomic predicates can be of the form&lt;br /&gt;
* &amp;lt;TT &amp;gt;&amp;lt;VAR &amp;gt;DeviceClass&amp;lt;/VAR &amp;gt;.&amp;lt;VAR&amp;gt;attribute&amp;lt;/VAR &amp;gt; == &amp;lt;VAR &amp;gt;value&amp;lt;/VAR &amp;gt;&amp;lt;/TT &amp;gt;&lt;br /&gt;
* &amp;lt;TT &amp;gt;&amp;lt;VAR &amp;gt;DeviceClass&amp;lt;/VAR &amp;gt;.&amp;lt;VAR &amp;gt;attribute&amp;lt;/VAR &amp;gt; &amp;amp; &amp;lt;VAR &amp;gt;value&amp;lt;/VAR &amp;gt;&amp;lt;/TT &amp;gt;&lt;br /&gt;
the latter form meaning that the Solid attribute may have a set of values, and the specified value must be a part of that set.  &lt;br /&gt;
&lt;br /&gt;
For example, the predicate &amp;lt;TT &amp;gt;OpticalDisc.availableContent &amp;amp; 'Audio'&amp;lt;/TT &amp;gt; means that the device medium is an optical disc and that it contains audio tracks and possibly something else, while the hypothetical predicate &amp;lt;TT &amp;gt;OpticalDisc.availableContent == 'Audio'&amp;lt;/TT &amp;gt; means that a matching device contains audio tracks and nothing else.&lt;br /&gt;
&lt;br /&gt;
Atomic predicates can be composed using the keywords &amp;lt;TT &amp;gt;AND&amp;lt;/TT &amp;gt; and &amp;lt;TT &amp;gt;OR&amp;lt;/TT &amp;gt; and parentheses.  In practice, it is easiest to create a custom action with '''System Settings''' and peek the description from the custom action desktop file (within the user profile directory).&lt;br /&gt;
&lt;br /&gt;
== Executing actions ==&lt;br /&gt;
A matching action can be selected for execution by the user.  When that happens, the command line in the Exec key of the action is executed given the device as a parameter.  The location and value of the parameter is specified in the following way:&lt;br /&gt;
&amp;lt;DL &lt;br /&gt;
&amp;gt;&amp;lt;DT &amp;gt;&amp;lt;TT &amp;gt;%f&amp;lt;/TT &amp;gt;&amp;lt;DD &amp;gt;Device mount point location, if applicable &lt;br /&gt;
&amp;lt;DT &amp;gt;&amp;lt;TT &amp;gt;%d&amp;lt;/TT &amp;gt;&amp;lt;DD &amp;gt;Device special file path&lt;br /&gt;
&amp;lt;DT &amp;gt;&amp;lt;TT &amp;gt;%i&amp;lt;/TT &lt;br /&gt;
&amp;gt;&amp;lt;DD &amp;gt;Device identifier, as if returned by the command &amp;lt;TT &amp;gt;solid-hardware&amp;lt;/TT &amp;gt;&amp;lt;/DL &amp;gt;&lt;br /&gt;
&lt;br /&gt;
So you are free to choose whatever command syntax your application supports.  Note, however, that the forms &amp;lt;TT &amp;gt;%d&amp;lt;/TT &amp;gt; and &amp;lt;TT &amp;gt;%i&amp;lt;/TT &amp;gt; are deprecated by the Free Desktop standard and may be discontinued.&lt;br /&gt;
&lt;br /&gt;
== Installing actions ==&lt;br /&gt;
You install system-wide actions in the directory where the '''hotplug''' data engine will look for them (see [[#Actions and devices|above]]).  The action is available immediately after installation.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions</id>
		<title>Development/Tutorials/Solid/Device Actions</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions"/>
				<updated>2010-09-15T21:33:03Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Executing actions */ Installing&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The '''Device Notifier''' is a plasmoid that is responsible for handling device events.  When new data device is inserted or detected by '''Solid''', it gets added to the Device Notifier menu.  Each device has a set of ''actions'' the user can perform on the device, depending on the device type and its contents.  For example, when the media is an audio CD, the Device Notifier offers you to play that CD using '''Amarok'''.  The default actions are not a part of '''Plasma'''; rather, each one is installed by the application that handles the action, and goes away when the application is removed.&lt;br /&gt;
&lt;br /&gt;
You can add your own actions and modify existing ones using the '''Device Actions''' system setting module; however, such changes are limited to the user that requests the change.  If you want to install a custom action along with your application, you have to dig a bit deeper.&lt;br /&gt;
&lt;br /&gt;
== Anatomy of an action ==&lt;br /&gt;
&lt;br /&gt;
An Action file is a desktop configuration file similar to the following one:&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Desktop Entry]&lt;br /&gt;
X-KDE-Solid-Predicate=OpticalDisc.availableContent &amp;amp; 'Audio'&lt;br /&gt;
Type=Service&lt;br /&gt;
Actions=Play;&lt;br /&gt;
&lt;br /&gt;
[Desktop Action Play]&lt;br /&gt;
Name=Play Audio CD with Amarok&lt;br /&gt;
Name[fr]=Jouer CD Audio avec Amarok&lt;br /&gt;
# names in other languages&lt;br /&gt;
Icon=amarok&lt;br /&gt;
Exec=amarok --cdplay %f&lt;br /&gt;
&amp;lt;/code &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Actions and devices ==&lt;br /&gt;
&lt;br /&gt;
The '''Device Notifier''' gets the devices and their corresponding actions by interrogating its data engine called '''hotplug'''.  The '''hotplug''' data engine gets the set of devices from '''Solid''' and the set of actions from the subdirectories {{path|./solid/actions}} relative to the application settings path in '''KDE'''.  The set of actions pertaining to each device is then obtained by evaluating the Solid Predicate specified in the action against the physical and logical properties of the device; if the predicate holds, the action is included.&lt;br /&gt;
&lt;br /&gt;
== Action predicates ==&lt;br /&gt;
The predicate for each action is specified in the entry &amp;lt;TT &amp;gt;X-KDE-Solid-Predicate&amp;lt;/TT &amp;gt;.  The syntax of the predicate allows to construct an object of class '''Solid::Predicate''' out of it.&lt;br /&gt;
&lt;br /&gt;
Atomic predicates can be of the form&lt;br /&gt;
* &amp;lt;TT &amp;gt;&amp;lt;VAR &amp;gt;DeviceClass&amp;lt;/VAR &amp;gt;.&amp;lt;VAR&amp;gt;attribute&amp;lt;/VAR &amp;gt; == &amp;lt;VAR &amp;gt;value&amp;lt;/VAR &amp;gt;&amp;lt;/TT &amp;gt;&lt;br /&gt;
* &amp;lt;TT &amp;gt;&amp;lt;VAR &amp;gt;DeviceClass&amp;lt;/VAR &amp;gt;.&amp;lt;VAR &amp;gt;attribute&amp;lt;/VAR &amp;gt; &amp;amp; &amp;lt;VAR &amp;gt;value&amp;lt;/VAR &amp;gt;&amp;lt;/TT &amp;gt;&lt;br /&gt;
the latter form meaning that the Solid attribute may have a set of values, and the specified value must be a part of that set.  &lt;br /&gt;
&lt;br /&gt;
For example, the predicate &amp;lt;TT &amp;gt;OpticalDisc.availableContent &amp;amp; 'Audio'&amp;lt;/TT &amp;gt; means that the device medium is an optical disc and that it contains audio tracks and possibly something else, while the hypothetical predicate &amp;lt;TT &amp;gt;OpticalDisc.availableContent == 'Audio'&amp;lt;/TT &amp;gt; means that a matching device contains audio tracks and nothing else.&lt;br /&gt;
&lt;br /&gt;
Atomic predicates can be composed using the keywords &amp;lt;TT &amp;gt;AND&amp;lt;/TT &amp;gt; and &amp;lt;TT &amp;gt;OR&amp;lt;/TT &amp;gt; and parentheses.  In practice, it is easiest to create a custom action with '''System Settings''' and peek the description from the custom action desktop file (within the user profile directory).&lt;br /&gt;
&lt;br /&gt;
== Executing actions ==&lt;br /&gt;
A matching action can be selected for execution by the user.  When that happens, the command line in the Exec key of the action is executed given the device as a parameter.  The location and value of the parameter is specified in the following way:&lt;br /&gt;
&amp;lt;DL &lt;br /&gt;
&amp;gt;&amp;lt;DT &amp;gt;&amp;lt;TT &amp;gt;%f&amp;lt;/TT &amp;gt;&amp;lt;DD &amp;gt;Device mount point location, if applicable &lt;br /&gt;
&amp;lt;DT &amp;gt;&amp;lt;TT &amp;gt;%d&amp;lt;/TT &amp;gt;&amp;lt;DD &amp;gt;Device special file path&lt;br /&gt;
&amp;lt;DT &amp;gt;&amp;lt;TT &amp;gt;%i&amp;lt;/TT &lt;br /&gt;
&amp;gt;&amp;lt;DD &amp;gt;Device identifier, as if returned by the command &amp;lt;TT &amp;gt;solid-hardware&amp;lt;/TT &amp;gt;&amp;lt;/DL &amp;gt;&lt;br /&gt;
&lt;br /&gt;
So you are free to choose whatever command syntax your application supports.  Note, however, that the forms &amp;lt;TT &amp;gt;%d&amp;lt;/TT &amp;gt; and &amp;lt;TT &amp;gt;%i&amp;lt;/TT &amp;gt; are deprecated by the Free Desktop standard and may be discontinued.&lt;br /&gt;
&lt;br /&gt;
== Installing actions ==&lt;br /&gt;
You install system-wide actions in the directory where the '''hotplug''' data engine will look for them (see above).  The action is available immediately after installation.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions</id>
		<title>Development/Tutorials/Solid/Device Actions</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions"/>
				<updated>2010-09-15T21:30:37Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Action predicates */ executing actions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The '''Device Notifier''' is a plasmoid that is responsible for handling device events.  When new data device is inserted or detected by '''Solid''', it gets added to the Device Notifier menu.  Each device has a set of ''actions'' the user can perform on the device, depending on the device type and its contents.  For example, when the media is an audio CD, the Device Notifier offers you to play that CD using '''Amarok'''.  The default actions are not a part of '''Plasma'''; rather, each one is installed by the application that handles the action, and goes away when the application is removed.&lt;br /&gt;
&lt;br /&gt;
You can add your own actions and modify existing ones using the '''Device Actions''' system setting module; however, such changes are limited to the user that requests the change.  If you want to install a custom action along with your application, you have to dig a bit deeper.&lt;br /&gt;
&lt;br /&gt;
== Anatomy of an action ==&lt;br /&gt;
&lt;br /&gt;
An Action file is a desktop configuration file similar to the following one:&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Desktop Entry]&lt;br /&gt;
X-KDE-Solid-Predicate=OpticalDisc.availableContent &amp;amp; 'Audio'&lt;br /&gt;
Type=Service&lt;br /&gt;
Actions=Play;&lt;br /&gt;
&lt;br /&gt;
[Desktop Action Play]&lt;br /&gt;
Name=Play Audio CD with Amarok&lt;br /&gt;
Name[fr]=Jouer CD Audio avec Amarok&lt;br /&gt;
# names in other languages&lt;br /&gt;
Icon=amarok&lt;br /&gt;
Exec=amarok --cdplay %f&lt;br /&gt;
&amp;lt;/code &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Actions and devices ==&lt;br /&gt;
&lt;br /&gt;
The '''Device Notifier''' gets the devices and their corresponding actions by interrogating its data engine called '''hotplug'''.  The '''hotplug''' data engine gets the set of devices from '''Solid''' and the set of actions from the subdirectories {{path|./solid/actions}} relative to the application settings path in '''KDE'''.  The set of actions pertaining to each device is then obtained by evaluating the Solid Predicate specified in the action against the physical and logical properties of the device; if the predicate holds, the action is included.&lt;br /&gt;
&lt;br /&gt;
== Action predicates ==&lt;br /&gt;
The predicate for each action is specified in the entry &amp;lt;TT &amp;gt;X-KDE-Solid-Predicate&amp;lt;/TT &amp;gt;.  The syntax of the predicate allows to construct an object of class '''Solid::Predicate''' out of it.&lt;br /&gt;
&lt;br /&gt;
Atomic predicates can be of the form&lt;br /&gt;
* &amp;lt;TT &amp;gt;&amp;lt;VAR &amp;gt;DeviceClass&amp;lt;/VAR &amp;gt;.&amp;lt;VAR&amp;gt;attribute&amp;lt;/VAR &amp;gt; == &amp;lt;VAR &amp;gt;value&amp;lt;/VAR &amp;gt;&amp;lt;/TT &amp;gt;&lt;br /&gt;
* &amp;lt;TT &amp;gt;&amp;lt;VAR &amp;gt;DeviceClass&amp;lt;/VAR &amp;gt;.&amp;lt;VAR &amp;gt;attribute&amp;lt;/VAR &amp;gt; &amp;amp; &amp;lt;VAR &amp;gt;value&amp;lt;/VAR &amp;gt;&amp;lt;/TT &amp;gt;&lt;br /&gt;
the latter form meaning that the Solid attribute may have a set of values, and the specified value must be a part of that set.  &lt;br /&gt;
&lt;br /&gt;
For example, the predicate &amp;lt;TT &amp;gt;OpticalDisc.availableContent &amp;amp; 'Audio'&amp;lt;/TT &amp;gt; means that the device medium is an optical disc and that it contains audio tracks and possibly something else, while the hypothetical predicate &amp;lt;TT &amp;gt;OpticalDisc.availableContent == 'Audio'&amp;lt;/TT &amp;gt; means that a matching device contains audio tracks and nothing else.&lt;br /&gt;
&lt;br /&gt;
Atomic predicates can be composed using the keywords &amp;lt;TT &amp;gt;AND&amp;lt;/TT &amp;gt; and &amp;lt;TT &amp;gt;OR&amp;lt;/TT &amp;gt; and parentheses.  In practice, it is easiest to create a custom action with '''System Settings''' and peek the description from the custom action desktop file (within the user profile directory).&lt;br /&gt;
&lt;br /&gt;
== Executing actions ==&lt;br /&gt;
A matching action can be selected for execution by the user.  When that happens, the command line in the Exec key of the action is executed given the device as a parameter.  The location and value of the parameter is specified in the following way:&lt;br /&gt;
&amp;lt;DL &lt;br /&gt;
&amp;gt;&amp;lt;DT &amp;gt;&amp;lt;TT &amp;gt;%f&amp;lt;/TT &amp;gt;&amp;lt;DD &amp;gt;Device mount point location, if applicable &lt;br /&gt;
&amp;lt;DT &amp;gt;&amp;lt;TT &amp;gt;%d&amp;lt;/TT &amp;gt;&amp;lt;DD &amp;gt;Device special file path&lt;br /&gt;
&amp;lt;DT &amp;gt;&amp;lt;TT &amp;gt;%i&amp;lt;/TT &lt;br /&gt;
&amp;gt;&amp;lt;DD &amp;gt;Device identifier, as if returned by the command &amp;lt;TT &amp;gt;solid-hardware&amp;lt;/TT &amp;gt;&amp;lt;/DL &amp;gt;&lt;br /&gt;
&lt;br /&gt;
So you are free to choose whatever command syntax your application supports.  Note, however, that the forms &amp;lt;TT &amp;gt;%d&amp;lt;/TT &amp;gt; and &amp;lt;TT &amp;gt;%i&amp;lt;/TT &amp;gt; are deprecated by the Free Desktop standard and may be discontinued.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions</id>
		<title>Development/Tutorials/Solid/Device Actions</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions"/>
				<updated>2010-09-15T21:15:56Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Atomic predicates */ composite actions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The '''Device Notifier''' is a plasmoid that is responsible for handling device events.  When new data device is inserted or detected by '''Solid''', it gets added to the Device Notifier menu.  Each device has a set of ''actions'' the user can perform on the device, depending on the device type and its contents.  For example, when the media is an audio CD, the Device Notifier offers you to play that CD using '''Amarok'''.  The default actions are not a part of '''Plasma'''; rather, each one is installed by the application that handles the action, and goes away when the application is removed.&lt;br /&gt;
&lt;br /&gt;
You can add your own actions and modify existing ones using the '''Device Actions''' system setting module; however, such changes are limited to the user that requests the change.  If you want to install a custom action along with your application, you have to dig a bit deeper.&lt;br /&gt;
&lt;br /&gt;
== Anatomy of an action ==&lt;br /&gt;
&lt;br /&gt;
An Action file is a desktop configuration file similar to the following one:&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Desktop Entry]&lt;br /&gt;
X-KDE-Solid-Predicate=OpticalDisc.availableContent &amp;amp; 'Audio'&lt;br /&gt;
Type=Service&lt;br /&gt;
Actions=Play;&lt;br /&gt;
&lt;br /&gt;
[Desktop Action Play]&lt;br /&gt;
Name=Play Audio CD with Amarok&lt;br /&gt;
Name[fr]=Jouer CD Audio avec Amarok&lt;br /&gt;
# names in other languages&lt;br /&gt;
Icon=amarok&lt;br /&gt;
Exec=amarok --cdplay %f&lt;br /&gt;
&amp;lt;/code &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Actions and devices ==&lt;br /&gt;
&lt;br /&gt;
The '''Device Notifier''' gets the devices and their corresponding actions by interrogating its data engine called '''hotplug'''.  The '''hotplug''' data engine gets the set of devices from '''Solid''' and the set of actions from the subdirectories {{path|./solid/actions}} relative to the application settings path in '''KDE'''.  The set of actions pertaining to each device is then obtained by evaluating the Solid Predicate specified in the action against the physical and logical properties of the device; if the predicate holds, the action is included.&lt;br /&gt;
&lt;br /&gt;
== Action predicates ==&lt;br /&gt;
The predicate for each action is specified in the entry &amp;lt;TT &amp;gt;X-KDE-Solid-Predicate&amp;lt;/TT &amp;gt;.  The syntax of the predicate allows to construct an object of class '''Solid::Predicate''' out of it.&lt;br /&gt;
&lt;br /&gt;
Atomic predicates can be of the form&lt;br /&gt;
* &amp;lt;TT &amp;gt;&amp;lt;VAR &amp;gt;DeviceClass&amp;lt;/VAR &amp;gt;.&amp;lt;VAR&amp;gt;attribute&amp;lt;/VAR &amp;gt; == &amp;lt;VAR &amp;gt;value&amp;lt;/VAR &amp;gt;&amp;lt;/TT &amp;gt;&lt;br /&gt;
* &amp;lt;TT &amp;gt;&amp;lt;VAR &amp;gt;DeviceClass&amp;lt;/VAR &amp;gt;.&amp;lt;VAR &amp;gt;attribute&amp;lt;/VAR &amp;gt; &amp;amp; &amp;lt;VAR &amp;gt;value&amp;lt;/VAR &amp;gt;&amp;lt;/TT &amp;gt;&lt;br /&gt;
the latter form meaning that the Solid attribute may have a set of values, and the specified value must be a part of that set.  &lt;br /&gt;
&lt;br /&gt;
For example, the predicate &amp;lt;TT &amp;gt;OpticalDisc.availableContent &amp;amp; 'Audio'&amp;lt;/TT &amp;gt; means that the device medium is an optical disc and that it contains audio tracks and possibly something else, while the hypothetical predicate &amp;lt;TT &amp;gt;OpticalDisc.availableContent == 'Audio'&amp;lt;/TT &amp;gt; means that a matching device contains audio tracks and nothing else.&lt;br /&gt;
&lt;br /&gt;
Atomic predicates can be composed using the keywords &amp;lt;TT &amp;gt;AND&amp;lt;/TT &amp;gt; and &amp;lt;TT &amp;gt;OR&amp;lt;/TT &amp;gt; and parentheses.  In practice, it is easiest to create a custom action with '''System Settings''' and peek the description from the custom action desktop file (within the user profile directory).&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions</id>
		<title>Development/Tutorials/Solid/Device Actions</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions"/>
				<updated>2010-09-15T21:11:59Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Action predicates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The '''Device Notifier''' is a plasmoid that is responsible for handling device events.  When new data device is inserted or detected by '''Solid''', it gets added to the Device Notifier menu.  Each device has a set of ''actions'' the user can perform on the device, depending on the device type and its contents.  For example, when the media is an audio CD, the Device Notifier offers you to play that CD using '''Amarok'''.  The default actions are not a part of '''Plasma'''; rather, each one is installed by the application that handles the action, and goes away when the application is removed.&lt;br /&gt;
&lt;br /&gt;
You can add your own actions and modify existing ones using the '''Device Actions''' system setting module; however, such changes are limited to the user that requests the change.  If you want to install a custom action along with your application, you have to dig a bit deeper.&lt;br /&gt;
&lt;br /&gt;
== Anatomy of an action ==&lt;br /&gt;
&lt;br /&gt;
An Action file is a desktop configuration file similar to the following one:&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Desktop Entry]&lt;br /&gt;
X-KDE-Solid-Predicate=OpticalDisc.availableContent &amp;amp; 'Audio'&lt;br /&gt;
Type=Service&lt;br /&gt;
Actions=Play;&lt;br /&gt;
&lt;br /&gt;
[Desktop Action Play]&lt;br /&gt;
Name=Play Audio CD with Amarok&lt;br /&gt;
Name[fr]=Jouer CD Audio avec Amarok&lt;br /&gt;
# names in other languages&lt;br /&gt;
Icon=amarok&lt;br /&gt;
Exec=amarok --cdplay %f&lt;br /&gt;
&amp;lt;/code &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Actions and devices ==&lt;br /&gt;
&lt;br /&gt;
The '''Device Notifier''' gets the devices and their corresponding actions by interrogating its data engine called '''hotplug'''.  The '''hotplug''' data engine gets the set of devices from '''Solid''' and the set of actions from the subdirectories {{path|./solid/actions}} relative to the application settings path in '''KDE'''.  The set of actions pertaining to each device is then obtained by evaluating the Solid Predicate specified in the action against the physical and logical properties of the device; if the predicate holds, the action is included.&lt;br /&gt;
&lt;br /&gt;
== Action predicates ==&lt;br /&gt;
The predicate for each action is specified in the entry &amp;lt;TT &amp;gt;X-KDE-Solid-Predicate&amp;lt;/TT &amp;gt;.  The syntax of the predicate allows to construct an object of class '''Solid::Predicate''' out of it.&lt;br /&gt;
&lt;br /&gt;
=== Atomic predicates ===&lt;br /&gt;
Atomic predicates can be of the form&lt;br /&gt;
* &amp;lt;TT &amp;gt;&amp;lt;VAR &amp;gt;DeviceClass&amp;lt;/VAR &amp;gt;.&amp;lt;VAR&amp;gt;attribute&amp;lt;/VAR &amp;gt; == &amp;lt;VAR &amp;gt;value&amp;lt;/VAR &amp;gt;&amp;lt;/TT &amp;gt;&lt;br /&gt;
* &amp;lt;TT &amp;gt;&amp;lt;VAR &amp;gt;DeviceClass&amp;lt;/VAR &amp;gt;.&amp;lt;VAR &amp;gt;attribute&amp;lt;/VAR &amp;gt; &amp;amp; &amp;lt;VAR &amp;gt;value&amp;lt;/VAR &amp;gt;&amp;lt;/TT &amp;gt;&lt;br /&gt;
the latter form meaning that the Solid attribute may have a set of values, and the specified value must be a part of that set.  &lt;br /&gt;
&lt;br /&gt;
For example, the predicate &amp;lt;TT &amp;gt;OpticalDisc.availableContent &amp;amp; 'Audio'&amp;lt;/TT &amp;gt; means that the device medium is an optical disc and that it contains audio tracks and possibly something else, while the hypothetical predicate &amp;lt;TT &amp;gt;OpticalDisc.availableContent == 'Audio'&amp;lt;/TT &amp;gt; means that a matching device contains audio tracks and nothing else.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions</id>
		<title>Development/Tutorials/Solid/Device Actions</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions"/>
				<updated>2010-09-15T21:11:15Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Actions and devices */ Predicates&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The '''Device Notifier''' is a plasmoid that is responsible for handling device events.  When new data device is inserted or detected by '''Solid''', it gets added to the Device Notifier menu.  Each device has a set of ''actions'' the user can perform on the device, depending on the device type and its contents.  For example, when the media is an audio CD, the Device Notifier offers you to play that CD using '''Amarok'''.  The default actions are not a part of '''Plasma'''; rather, each one is installed by the application that handles the action, and goes away when the application is removed.&lt;br /&gt;
&lt;br /&gt;
You can add your own actions and modify existing ones using the '''Device Actions''' system setting module; however, such changes are limited to the user that requests the change.  If you want to install a custom action along with your application, you have to dig a bit deeper.&lt;br /&gt;
&lt;br /&gt;
== Anatomy of an action ==&lt;br /&gt;
&lt;br /&gt;
An Action file is a desktop configuration file similar to the following one:&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Desktop Entry]&lt;br /&gt;
X-KDE-Solid-Predicate=OpticalDisc.availableContent &amp;amp; 'Audio'&lt;br /&gt;
Type=Service&lt;br /&gt;
Actions=Play;&lt;br /&gt;
&lt;br /&gt;
[Desktop Action Play]&lt;br /&gt;
Name=Play Audio CD with Amarok&lt;br /&gt;
Name[fr]=Jouer CD Audio avec Amarok&lt;br /&gt;
# names in other languages&lt;br /&gt;
Icon=amarok&lt;br /&gt;
Exec=amarok --cdplay %f&lt;br /&gt;
&amp;lt;/code &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Actions and devices ==&lt;br /&gt;
&lt;br /&gt;
The '''Device Notifier''' gets the devices and their corresponding actions by interrogating its data engine called '''hotplug'''.  The '''hotplug''' data engine gets the set of devices from '''Solid''' and the set of actions from the subdirectories {{path|./solid/actions}} relative to the application settings path in '''KDE'''.  The set of actions pertaining to each device is then obtained by evaluating the Solid Predicate specified in the action against the physical and logical properties of the device; if the predicate holds, the action is included.&lt;br /&gt;
&lt;br /&gt;
== Action predicates ==&lt;br /&gt;
The predicate for each action is specified in the entry &amp;lt;TT &amp;gt;X-KDE-Solid-Predicate&amp;lt;/TT &amp;gt;.  The syntax is of the predicate allows to construct an object of class '''Solid::Predicate''' out of it.&lt;br /&gt;
&lt;br /&gt;
=== Atomic predicates ===&lt;br /&gt;
Atomic predicates can be of the form&lt;br /&gt;
* &amp;lt;TT &amp;gt;&amp;lt;VAR &amp;gt;DeviceClass&amp;lt;/VAR &amp;gt;.&amp;lt;VAR&amp;gt;attribute&amp;lt;/VAR &amp;gt; == &amp;lt;VAR &amp;gt;value&amp;lt;/VAR &amp;gt;&amp;lt;/TT &amp;gt;&lt;br /&gt;
* &amp;lt;TT &amp;gt;&amp;lt;VAR &amp;gt;DeviceClass&amp;lt;/VAR &amp;gt;.&amp;lt;VAR &amp;gt;attribute&amp;lt;/VAR &amp;gt; &amp;amp; &amp;lt;VAR &amp;gt;value&amp;lt;/VAR &amp;gt;&amp;lt;/TT &amp;gt;&lt;br /&gt;
the latter form meaning that the Solid attribute may have a set of values, and the specified value must be a part of that set.  &lt;br /&gt;
&lt;br /&gt;
For example, the predicate &amp;lt;TT &amp;gt;OpticalDisc.availableContent &amp;amp; 'Audio'&amp;lt;/TT &amp;gt; means that the device medium is an optical disc and that it contains audio tracks and possibly something else, while the hypothetical predicate &amp;lt;TT &amp;gt;OpticalDisc.availableContent == 'Audio'&amp;lt;/TT &amp;gt; means that a matching device contains audio tracks and nothing else.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions</id>
		<title>Development/Tutorials/Solid/Device Actions</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions"/>
				<updated>2010-09-15T20:58:44Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Introduction */ Anatomy&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The '''Device Notifier''' is a plasmoid that is responsible for handling device events.  When new data device is inserted or detected by '''Solid''', it gets added to the Device Notifier menu.  Each device has a set of ''actions'' the user can perform on the device, depending on the device type and its contents.  For example, when the media is an audio CD, the Device Notifier offers you to play that CD using '''Amarok'''.  The default actions are not a part of '''Plasma'''; rather, each one is installed by the application that handles the action, and goes away when the application is removed.&lt;br /&gt;
&lt;br /&gt;
You can add your own actions and modify existing ones using the '''Device Actions''' system setting module; however, such changes are limited to the user that requests the change.  If you want to install a custom action along with your application, you have to dig a bit deeper.&lt;br /&gt;
&lt;br /&gt;
== Anatomy of an action ==&lt;br /&gt;
&lt;br /&gt;
An Action file is a desktop configuration file similar to the following one:&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Desktop Entry]&lt;br /&gt;
X-KDE-Solid-Predicate=OpticalDisc.availableContent &amp;amp; 'Audio'&lt;br /&gt;
Type=Service&lt;br /&gt;
Actions=Play;&lt;br /&gt;
&lt;br /&gt;
[Desktop Action Play]&lt;br /&gt;
Name=Play Audio CD with Amarok&lt;br /&gt;
Name[fr]=Jouer CD Audio avec Amarok&lt;br /&gt;
# names in other languages&lt;br /&gt;
Icon=amarok&lt;br /&gt;
Exec=amarok --cdplay %f&lt;br /&gt;
&amp;lt;/code &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Actions and devices ==&lt;br /&gt;
&lt;br /&gt;
The '''Device Notifier''' gets the devices and their corresponding actions by interrogating its data engine called '''hotplug'''.  The '''hotplug''' data engine gets the set of devices from '''Solid''' and the set of actions from the subdirectories {{path|./solid/actions}} relative to the application settings path in '''KDE'''.  The set of actions pertaining to each device is then obtained by evaluating the Solid Predicate specified in the action against the physical and logical properties of the device; if the predicate holds, the action is included.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions</id>
		<title>Development/Tutorials/Solid/Device Actions</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Solid/Device_Actions"/>
				<updated>2010-09-15T20:33:26Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: Introduction&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
The Device Notifier is a plasmoid that is responsible for handling device events.  When new data device is inserted or detected by Solid, it gets added to the Device Notifier menu.  Each device has a set of actions the user can perform on the device, depending on the device type and its contents.  For example, when the media is an audio CD, the Device Notifier offers you to play that CD using Amarok.  The default actions are not a part of Plasma; each one is installed by the application that handles the action, and goes away when the application is removed.&lt;br /&gt;
&lt;br /&gt;
You can add your own actions and modify existing ones using the Device Actions system setting module; however, such changes are limited to the user that requests the change.  If you want to install a custom action along with your application, you have to dig a bit deeper.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Plasma</id>
		<title>Development/Tutorials/Plasma</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Plasma"/>
				<updated>2010-09-15T20:21:11Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Theme development */ Creating a Device Notifier action&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Tutorials/Plasma}}&lt;br /&gt;
&lt;br /&gt;
== Plasma Programming with C++ ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/GettingStarted|Getting Started With Plasmoids]]&lt;br /&gt;
:''Creating your first plasmoid in C++ with SVG background, icon and text''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/DataEngines|Writing a DataEngine]]&lt;br /&gt;
:''DataEngines provide a standardized interface to various data sources for visualizations to use. Learn what a DataEngine is and how to write one of your own.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/UsingExtenders|How to use extenders in your Plasmoid]]&lt;br /&gt;
:''A simple example that shows how to use extenders in a Plasmoid.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/AbstractRunner|Creating Runners]]&lt;br /&gt;
:''Runners are plugins that provide action-based search functionality in the Plasma workspace &amp;quot;run command&amp;quot; dialog. These plugins can be used by any application that links again libplasma.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/WallpaperHelloWorld|Wallpaper Tutorial 1]]&lt;br /&gt;
:''This tutorial shows you how to make a simple Hello World plasma wallpaper plugin.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/ShellDesign|Creating a Plasma Shell]]&lt;br /&gt;
:''This tutorial covers the essentials of writing a new Plasma shell from scratch. A must-read for anyone creating a new or modifying an existing Plasma Shell. Existing Plasma shells include Plasma Desktop, Plasma Netbook, Plasma Mobile, Plasma Media Center, Plasma Screensaver, Plasma KPart and Plasma KDM, and all follow the patterns documented here.''&lt;br /&gt;
&lt;br /&gt;
;[http://www.linux-magazine.com/w3/issue/114/036-040_plasma.pdf Creating Plasmoids]&lt;br /&gt;
:''May 2010 article from Linux Magazine''&lt;br /&gt;
&lt;br /&gt;
;[http://www.ibm.com/developerworks/linux/library/l-kde-plasmoids/index.html Create Plasmoids using KDevelop]&lt;br /&gt;
:''Article explaining the structure of Plasma and how to create a Plasmoid''&lt;br /&gt;
&lt;br /&gt;
;[http://community.kde.org/User:Mxttie#Adding_configuration Adding configuration to your plasmoid]&lt;br /&gt;
:''Article explaining how to add a configuration dialog to your plasmoid.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/ApplicationShell|Integrate Plasma in Applications]]&lt;br /&gt;
:''This tutorial shows you how to make an application dashboard based on Plasma technologies.''&lt;br /&gt;
&lt;br /&gt;
== Plasma Programming with JavaScript ==&lt;br /&gt;
&lt;br /&gt;
Plasma has built-in JavaScript (also known as ECMAScript, and often referred to as QtScript in the context of Qt) scripting support without requiring any external dependencies.&lt;br /&gt;
&lt;br /&gt;
=== Plasmoids ===&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/JavaScript/GettingStarted|Getting Started]]&lt;br /&gt;
:''Creating and running your first plasmoid in JavaScript''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/JavaScript/DataEngine|Getting Data]]&lt;br /&gt;
:''How to retreive data from a data engine''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/JavaScript/NowPlaying|Now Playing]]&lt;br /&gt;
:''Slightly more advanced data engine usage: displaying what's currently playing''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/JavaScript/SystemMonitor|System Monitor]]&lt;br /&gt;
:''How to access systemmonitor data engine''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/JavaScript/CheatSheet|Cheat Sheet]]&lt;br /&gt;
:''A cheat sheet, rather than a tutorial, of things to remember and watch out for when developing JavaScript plasmoids''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/JavaScript/API|API Reference]]&lt;br /&gt;
:''The Simplified JavaScript Plasmoid API. Useful for referencing what is available in the runtime and as a study aid for the tutorials above.''&lt;br /&gt;
&lt;br /&gt;
=== Other Applications Of Javascript ===&lt;br /&gt;
;[[KDE_System_Administration/PlasmaDestkopScripting|Scripting Plasma Shells]]&lt;br /&gt;
:The KDE Plasma Desktop and Netbook provide means to manage the desktop shell (desktop, panels, widget) via scripts written in JavaScript. This article describes how to take advantage of this feature set as well as documents the full API. This is primarily a system administration tool, but may also be of interest to power users.&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/JavaScript/Animations|Javascript Animations]]&lt;br /&gt;
:''How to write Animations using Javascript for use in Plasma applications''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/ComicPlugin|Creating Comic Plugins]]&lt;br /&gt;
:''This guide shows you how to create a comic plugin for the comic plasmoid.''&lt;br /&gt;
&lt;br /&gt;
== Plasma Programming with Python ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/Python/GettingStarted|Getting Started]]&lt;br /&gt;
:''Creating and running your first plasmoid in Python''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/Python/Using widgets|Using widgets]]&lt;br /&gt;
:''Introduction to using Plasma widgets''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/Python/Using DataEngines|Using DataEngines]]&lt;br /&gt;
:''How to use DataEngines from a plasmoid''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/Python/Writing DataEngines|Writing DataEngines]]&lt;br /&gt;
:''How to write your own Plasma DataEngine''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/PythonPlasmoid|Writing a Plasmoid in Python]]&lt;br /&gt;
:''Writing a simple battery graph in python''&lt;br /&gt;
&lt;br /&gt;
== Plasma Programming with Ruby ==&lt;br /&gt;
;[[Development/Tutorials/Plasma/Ruby/GettingStarted|Getting Started]]&lt;br /&gt;
:''Creating and running your first plasmoid in Ruby''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/Ruby/Using widgets|Using widgets]]&lt;br /&gt;
:''Introduction to using Plasma widgets''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/Ruby/SimplePasteApplet|Writing a simple paste applet]]&lt;br /&gt;
:''A tutorial explaining how to set up a plasmoid, create a simple paste applet using widgets and add Plasma features seen elsewhere. Complete with tips for those who have never programmed before.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/Ruby/Writing DataEngines|Writing DataEngines]]&lt;br /&gt;
:''How to write your own Plasma DataEngine using Ruby''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/Ruby/Blinker|Use SVG artwork in the simplest way possible]]&lt;br /&gt;
:''Follow a fellow student as he asks around about SVG usage and explains why the code examples work. This is a wiki so feel free to add your own insights until this tutorial can be considered complete.''&lt;br /&gt;
&lt;br /&gt;
== Plasma Programming with Web Technologies (HTML/JS/CSS etc) ==&lt;br /&gt;
;[[Development/Tutorials/Plasma/Web/GettingStarted|Getting Started]]&lt;br /&gt;
:''Creating and running your first plasmoid in HTML''&lt;br /&gt;
&lt;br /&gt;
== Plasma integration ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/Device Notifier|Creating a Device Notifier action]]&lt;br /&gt;
:''When your application is interested in removable hardware''&lt;br /&gt;
&lt;br /&gt;
== Theme development ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/Theme|Creating a Plasma Theme Quickstart]]&lt;br /&gt;
:''A quick guide to creating your first Plasma theme''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/ThemeDetails|The Plasma Theme Structure In Detail]]&lt;br /&gt;
:''A comprehensive guide to the contents of a Plasma SVG theme, including configuration options, wallpapers, on-disk layout, names of all standard SVG files and every element in them.''&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
* [[Projects/Plasma|Projects: Plasma]]&lt;br /&gt;
* [http://api.kde.org/4.x-api/kdelibs-apidocs/plasma/html/index.html Plasma api documentation]&lt;br /&gt;
* [http://techbase.kde.org/Projects/Plasma/Eclipse_Integration Plasma Eclipse Integration]&lt;br /&gt;
* The [https://mail.kde.org/mailman/listinfo/plasma-devel plasma-devel mailing list] and #plasma on IRC (irc.freenode.org).&lt;br /&gt;
&lt;br /&gt;
== Presentation Slides==&lt;br /&gt;
http://chani.wordpress.com/2009/04/25/quick-update-for-my-presentation/ Victory Calendar -- also link to websvn plasma playground in the odp file.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/User_talk:Yecril71pl</id>
		<title>User talk:Yecril71pl</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/User_talk:Yecril71pl"/>
				<updated>2010-09-14T19:49:43Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Bug: code cpp-qt n does not work */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Sidebar ==&lt;br /&gt;
&lt;br /&gt;
[[MediaWiki:Sidebar]] is not fully translated into Polish.  The translated messages should land in MediaWiki:''message''/pl.  Since only [[Project:Administrators]] can edit those messages, I am placing the text into the talk pages.&lt;br /&gt;
&lt;br /&gt;
* [[MediaWiki:navigation/pl]]&lt;br /&gt;
** mainpage|[[MediaWiki:Home/pl]]&lt;br /&gt;
** helppage|[[MediaWiki:help/pl]]&lt;br /&gt;
** recentchanges-url|[[MediaWiki:recentchanges/pl]]&lt;br /&gt;
&lt;br /&gt;
* [[MediaWiki:Sections/pl]]&lt;br /&gt;
** Getting_Started|[[MediaWiki:Getting started/pl]]&lt;br /&gt;
** Development|[[MediaWiki:Development/pl]]&lt;br /&gt;
** Schedules|[[MediaWiki:Schedules/pl]]&lt;br /&gt;
** Policies|[[MediaWiki:Policies/pl]]&lt;br /&gt;
** Contribute|[[MediaWiki:Contribute/pl]]&lt;br /&gt;
** Projects|[[MediaWiki:Projects/pl]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[User:Yecril71pl|Yecril71pl]] 16:05, 14 September 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Bug: code cpp-qt n does not work ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-zz &amp;gt;a;&amp;lt;/code &amp;gt;&lt;br /&gt;
&amp;lt;code cpp-qt n&amp;gt;a;&amp;lt;/code &amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/User_talk:Yecril71pl</id>
		<title>User talk:Yecril71pl</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/User_talk:Yecril71pl"/>
				<updated>2010-09-14T19:42:26Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Bug: code cpp-qt n does not work */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Sidebar ==&lt;br /&gt;
&lt;br /&gt;
[[MediaWiki:Sidebar]] is not fully translated into Polish.  The translated messages should land in MediaWiki:''message''/pl.  Since only [[Project:Administrators]] can edit those messages, I am placing the text into the talk pages.&lt;br /&gt;
&lt;br /&gt;
* [[MediaWiki:navigation/pl]]&lt;br /&gt;
** mainpage|[[MediaWiki:Home/pl]]&lt;br /&gt;
** helppage|[[MediaWiki:help/pl]]&lt;br /&gt;
** recentchanges-url|[[MediaWiki:recentchanges/pl]]&lt;br /&gt;
&lt;br /&gt;
* [[MediaWiki:Sections/pl]]&lt;br /&gt;
** Getting_Started|[[MediaWiki:Getting started/pl]]&lt;br /&gt;
** Development|[[MediaWiki:Development/pl]]&lt;br /&gt;
** Schedules|[[MediaWiki:Schedules/pl]]&lt;br /&gt;
** Policies|[[MediaWiki:Policies/pl]]&lt;br /&gt;
** Contribute|[[MediaWiki:Contribute/pl]]&lt;br /&gt;
** Projects|[[MediaWiki:Projects/pl]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[User:Yecril71pl|Yecril71pl]] 16:05, 14 September 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Bug: code cpp-qt n does not work ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt n&amp;gt;a;&amp;lt;/code &amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Help:Contents</id>
		<title>Help:Contents</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Help:Contents"/>
				<updated>2010-09-14T19:41:05Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Tips */ language codes reference&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Help:Contents}}&lt;br /&gt;
&lt;br /&gt;
Before you start to add or change content, please read the articles about the&lt;br /&gt;
* [[Help:Contribute|Contribute to TechBase]]&lt;br /&gt;
* [[Help:Wiki Structure|Wiki Structure]]&lt;br /&gt;
* [[Help:Wiki Translation|Translation into other Languages]]&lt;br /&gt;
* [[KDE_TechBase:Migrate_content|Migrate Content]]&lt;br /&gt;
* [[KDE_TechBase:Contributors|List of active contributors]], also contact points&lt;br /&gt;
&lt;br /&gt;
== Wiki Syntax ==&lt;br /&gt;
To get started with the MediaWiki syntax, read&lt;br /&gt;
* http://en.wikipedia.org/wiki/Help:Editing&lt;br /&gt;
* http://meta.wikimedia.org/wiki/Help:Table&lt;br /&gt;
* http://en.wikipedia.org/wiki/Wikipedia:Extended_image_syntax&lt;br /&gt;
* http://en.wikipedia.org/wiki/Help:Magic_words&lt;br /&gt;
&lt;br /&gt;
The most important commands are summarized in the [http://en.wikipedia.org/wiki/Wikipedia:Cheatsheet Wikipedia Cheatsheet]. Information about how to migrate content [[KDE TechBase:Migrate_content|can be found here]].&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
; Syntax highlighting&lt;br /&gt;
: Wrap your C++ Qt/KDE code snippets in &amp;lt;TT &amp;gt;&amp;amp;lt;code cpp&amp;amp;gt;&amp;lt;/TT &amp;gt;, &amp;lt;TT &amp;gt;&amp;amp;lt;code cpp n&amp;amp;gt;&amp;lt;/TT &amp;gt;, &amp;lt;TT &amp;gt;&amp;amp;lt;code cpp-qt&amp;amp;gt;&amp;lt;/TT &amp;gt; and &amp;lt;TT &amp;gt;&amp;amp;lt;/code&amp;amp;gt;&amp;lt;/TT &amp;gt; to get syntax highlighting (&amp;lt;TT &amp;gt;cpp&amp;lt;/TT &amp;gt; for C++, &amp;lt;TT &amp;gt;cpp-qt&amp;lt;/TT &amp;gt; for Qt) and numbered lines (&amp;lt;TT &amp;gt;n&amp;lt;/TT &amp;gt;). Replace &amp;lt;TT &amp;gt;cpp&amp;lt;/TT &amp;gt; with [http://www.mediawiki.org/wiki/Extension:SyntaxHighlight_GeSHi#Supported_languages the language used], e.g. &amp;lt;TT &amp;gt;ruby&amp;lt;/TT &amp;gt; for Ruby and &amp;lt;TT &amp;gt;python&amp;lt;/TT &amp;gt; for Python (soon). Use &amp;lt;TT &amp;gt;ini&amp;lt;/TT &amp;gt; for {{path|.desktop}} files, &amp;lt;TT &amp;gt;xml&amp;lt;/TT &amp;gt; for XML files.  Use plain &amp;lt;TT &amp;gt;&amp;amp;lt;code&amp;gt;&amp;lt;/TT &amp;gt; for wikitext (for now).&lt;br /&gt;
&lt;br /&gt;
== New Templates ==&lt;br /&gt;
To get a list of pages using a template, go to corresponding template page (e.g. [[Template:movepage]]) and click &amp;quot;''What links here''&amp;quot; in the toolbox.&lt;br /&gt;
&lt;br /&gt;
; [[Template:movepage|&amp;lt;nowiki&amp;gt;{{movepage|url}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to mark a page as not finished.&lt;br /&gt;
&lt;br /&gt;
; [[Template:Improve|&amp;lt;nowiki&amp;gt;{{improve|explanation}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Pages which need cleanups or contain empty sections and/or todos are marked with this template. Add an explanation if you want (optional)&lt;br /&gt;
&lt;br /&gt;
; [[Template:tip|&amp;lt;nowiki&amp;gt;{{tip|text}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to add a tip for the reader.&lt;br /&gt;
&lt;br /&gt;
; [[Template:note|&amp;lt;nowiki&amp;gt;{{note|text}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to add an explanatory note.&lt;br /&gt;
&lt;br /&gt;
; [[Template:warning|&amp;lt;nowiki&amp;gt;{{warning|text}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to add a warning.&lt;br /&gt;
&lt;br /&gt;
; [[Template:qt|&amp;lt;nowiki&amp;gt;{{qt|class-name}}&amp;lt;/nowiki&amp;gt;]] and [[Template:qt3|&amp;lt;nowiki&amp;gt;{{qt3|class-name}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to generate a link to a Qt class, e.g. QWidget. For Qt3 classes use &amp;lt;nowiki&amp;gt;{{qt3|class-name}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; [[Template:class|&amp;lt;nowiki&amp;gt;{{class|class-name}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to generate a link to a KDE class, e.g. KDialog.&lt;br /&gt;
&lt;br /&gt;
; [[Template:path|&amp;lt;nowiki&amp;gt;{{path|path-or-filename}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template for paths and filenames, this way all of them have a consistent style.&lt;br /&gt;
&lt;br /&gt;
; [[Template:bug|&amp;lt;nowiki&amp;gt;{{bug|123456}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to automatically create a link to KDE's bugzilla.&lt;br /&gt;
&lt;br /&gt;
; [[Template:KDE3|&amp;lt;nowiki&amp;gt;{{KDE3}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to mark the content of a page as applicable for either KDE 3. Don't tag technology agnostic pages. For KDE4 content, use &amp;lt;nowiki&amp;gt;[[Category:KDE4]]&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
; [[Template:TutorialBrowser|&amp;lt;nowiki&amp;gt;{{TutorialBrowser|series|name|pre|next|reading}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: A template for tutorial navigation&lt;br /&gt;
&lt;br /&gt;
; [[Template:Box|&amp;lt;nowiki&amp;gt;{{Box|caption|text|width|float}}&amp;lt;/nowiki&amp;gt;]]&lt;br /&gt;
: Use this template to create a box with a caption and a text. The width parameter is optional and can be specified absolute (400px) or relative (50%). The last parameter is the float value, which is also optional and defaults to center.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Help:Wiki_Translation</id>
		<title>Help:Wiki Translation</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Help:Wiki_Translation"/>
				<updated>2010-09-14T19:11:45Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Step 3: Language Navigation Bar */ style&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Help:Wiki_Translation}}&lt;br /&gt;
This article describes how to '''translate articles into other languages'''. Please make sure to also read the last section called [[#Important Notes|important notes]].&lt;br /&gt;
&lt;br /&gt;
== Step 1: Language Abbreviations ==&lt;br /&gt;
&lt;br /&gt;
As an example let us assume you want to translate the following page to german:&lt;br /&gt;
* [[Development/Tutorials]]&lt;br /&gt;
The language abbreviation for german is '''de''', thus, all articles will have the ending &amp;quot; (de)&amp;quot; (with a leading space).&lt;br /&gt;
&lt;br /&gt;
Reference:  [http://translatewiki.net/wiki/Special:SupportedLanguages list of language abbreviations].&lt;br /&gt;
&lt;br /&gt;
== Step 2: Create the Article ==&lt;br /&gt;
&lt;br /&gt;
Sometimes a link in the language navigation bar already exists. In that case, simply [http://support.mozilla.com/en/kb/Browsing+basics#clicking_a_link follow the link] you want to translate. Otherwise, create the article manually:&lt;br /&gt;
* [[Development/Tutorials (de)]]&lt;br /&gt;
'''As initial content simply use the content of the corresponding english page'''. This way, no content is missing, and other readers can help with the translation.&lt;br /&gt;
&lt;br /&gt;
== Step 3: Language Navigation Bar ==&lt;br /&gt;
&lt;br /&gt;
The article must contain the following template line in order to show the language navigation bar:&lt;br /&gt;
&amp;lt;CODE&amp;gt;{{Template:I18n/Language Navigation Bar|Development/Tutorials}}&amp;lt;/CODE&amp;gt;&lt;br /&gt;
This magic line expands to the language navigation bar for the article [[Development/Tutorials]]. Note, that the line does not contain the language abbreviation.&lt;br /&gt;
&lt;br /&gt;
== Step 4: Language Missing? ==&lt;br /&gt;
&lt;br /&gt;
If the language is missing, please search for the right abbreviation (see Step 1). In the example above this abbreviation is &amp;quot; (de)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Edit [[Template:I18n/Language Navigation Bar]] and add a line for the language you want to translate:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;span lang=&amp;quot;de&amp;quot;&amp;gt;[[{{{1}}}_(de)|Deutsch]]&amp;lt;/span&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Replace 'de' by the language abbreviation and adapt the visible name.&lt;br /&gt;
&lt;br /&gt;
== Important Notes ==&lt;br /&gt;
&lt;br /&gt;
As the wiki uses [[Help:Wiki Structure|subpages]] it is likely that translators run into the following issue.&lt;br /&gt;
&lt;br /&gt;
Assume the following pages exist:&lt;br /&gt;
 1. Development/Tutorials&lt;br /&gt;
 2. Development/Tutorials/Debugging&lt;br /&gt;
Further assume you want to translate (1) to german (postfix ''de'').&lt;br /&gt;
&lt;br /&gt;
The final page will be &lt;br /&gt;
 3. Development/Tutorials_(de)&lt;br /&gt;
The english content of (2) uses relative wiki links like &amp;lt;tt&amp;gt;/Debugging&amp;lt;/tt&amp;gt;. Translating ''Debugging'' in (3) might result in&lt;br /&gt;
 Development/Tutorials_(de)/Debugging      # wrong, or&lt;br /&gt;
 Development/Tutorials_(de)/Debugging_(de) # wrong&lt;br /&gt;
'''This is wrong.'''&lt;br /&gt;
&lt;br /&gt;
The rule of thumb is that the language abbreviation always appears at the very end of the article, that is the '''right link''' is supposed to be &lt;br /&gt;
 Development/Tutorials/Debugging_(de)&lt;br /&gt;
So be sure you adapt the links in the article to use absolute paths everywhere (i.e. no leading slash '/' in the wiki links).&lt;br /&gt;
&lt;br /&gt;
== Quality Assurance ==&lt;br /&gt;
&lt;br /&gt;
The system administrators and contributors try to keep a close watch at the content, but with foreign languages this is sometimes getting hard. It would be good, if you '''add yourself to the Watch list''' (just click ''Watch''). That way you will be noticed by mail whenever the article was changed. This will help to keep the wiki clean of e.g. spam, which unfortunately already happened.&lt;br /&gt;
&lt;br /&gt;
Also, consider to '''add yourself to the [[KDE_TechBase:Contributors#Translation_Teams|translation teams]]'''.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Help:Wiki_Translation_(pl)</id>
		<title>Help:Wiki Translation (pl)</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Help:Wiki_Translation_(pl)"/>
				<updated>2010-09-14T19:10:20Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Krok&amp;amp;nbsp;3.: Pasek nawigacji językowej */ styl&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Help:Wiki Translation}} &lt;br /&gt;
== Krok&amp;amp;nbsp;1.: Skróty nazw języków ==&lt;br /&gt;
&lt;br /&gt;
Przyjmijmy dla przykładu, że chcecie przetłumaczyć następującą stronę na polski:&lt;br /&gt;
* [[Development/Tutorials]]&lt;br /&gt;
Skrót nazwy języka polskiego to '''pl''', więc przetłumaczone artykuły mają nazwy kończące się na &amp;quot; (pl)&amp;quot; (z&amp;amp;nbsp;odstępem z&amp;amp;nbsp;przodu).&lt;br /&gt;
&lt;br /&gt;
Patrzcie:  [http://translatewiki.net/wiki/Special:SupportedLanguages spis nazw języków].&lt;br /&gt;
&lt;br /&gt;
== Krok&amp;amp;nbsp;2.: Tworzenie artykułu ==&lt;br /&gt;
&lt;br /&gt;
Nieraz potrzebny odnośnik istnieje już na pasku wyboru języka.  W&amp;amp;nbsp;tym wypadku po prostu wybierzcie odnośnik do strony tłumaczenia; inaczej utwórzcie tłumaczenie ręcznie:&lt;br /&gt;
* [[Development/Tutorials (pl)]]&lt;br /&gt;
'''Jako pierwotna zawartość tłumaczenia niech posłuży zawartość strony pierwotnej po angielsku.'''.  W&amp;amp;nbsp;ten sposób nie utracicie nic z&amp;amp;nbsp;zawartości.  Pamiętajcie, że inni użytkownicy również mogą pomóc w&amp;amp;nbsp;tłumaczeniu.&lt;br /&gt;
&lt;br /&gt;
== Krok&amp;amp;nbsp;3.: Pasek nawigacji językowej ==&lt;br /&gt;
&lt;br /&gt;
Aby pokazał się pasek nawigacji językowej, artykuł musi zawierać następujące wywołanie wzorca:&lt;br /&gt;
&amp;lt;CODE &amp;gt;{{Template:I18n/Language Navigation Bar|Development/Tutorials}}&amp;lt;/CODE &amp;gt;&lt;br /&gt;
To czarodziejskie zaklęcie rozwija się do paska nawigacji językowej dla artykułu [[Development/Tutorials]].  Uwaga: parametr wzorca &amp;lt;EM &amp;gt;nie zawiera&amp;lt;/EM &amp;gt; skrótu nazwy języka.&lt;br /&gt;
&lt;br /&gt;
{{translating|pl}}&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Help:Wiki_Translation_(pl)</id>
		<title>Help:Wiki Translation (pl)</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Help:Wiki_Translation_(pl)"/>
				<updated>2010-09-14T19:06:48Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Krok&amp;amp;nbsp;2.: Tworzenie artykułu */ Krok&amp;amp;nbsp;3.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Help:Wiki Translation}} &lt;br /&gt;
== Krok&amp;amp;nbsp;1.: Skróty nazw języków ==&lt;br /&gt;
&lt;br /&gt;
Przyjmijmy dla przykładu, że chcecie przetłumaczyć następującą stronę na polski:&lt;br /&gt;
* [[Development/Tutorials]]&lt;br /&gt;
Skrót nazwy języka polskiego to '''pl''', więc przetłumaczone artykuły mają nazwy kończące się na &amp;quot; (pl)&amp;quot; (z&amp;amp;nbsp;odstępem z&amp;amp;nbsp;przodu).&lt;br /&gt;
&lt;br /&gt;
Patrzcie:  [http://translatewiki.net/wiki/Special:SupportedLanguages spis nazw języków].&lt;br /&gt;
&lt;br /&gt;
== Krok&amp;amp;nbsp;2.: Tworzenie artykułu ==&lt;br /&gt;
&lt;br /&gt;
Nieraz potrzebny odnośnik istnieje już na pasku wyboru języka.  W&amp;amp;nbsp;tym wypadku po prostu wybierzcie odnośnik do strony tłumaczenia; inaczej utwórzcie tłumaczenie ręcznie:&lt;br /&gt;
* [[Development/Tutorials (pl)]]&lt;br /&gt;
'''Jako pierwotna zawartość tłumaczenia niech posłuży zawartość strony pierwotnej po angielsku.'''.  W&amp;amp;nbsp;ten sposób nie utracicie nic z&amp;amp;nbsp;zawartości.  Pamiętajcie, że inni użytkownicy również mogą pomóc w&amp;amp;nbsp;tłumaczeniu.&lt;br /&gt;
&lt;br /&gt;
== Krok&amp;amp;nbsp;3.: Pasek nawigacji językowej ==&lt;br /&gt;
&lt;br /&gt;
Aby pokazał się pasek nawigacji językowej, artykuł musi zawierać następujące wywołanie wzorca:&lt;br /&gt;
* &amp;lt;TT &amp;gt;&amp;lt;nowiki&amp;gt;{{Template:I18n/Language Navigation Bar|Development/Tutorials}}&amp;lt;/nowiki&amp;gt;&amp;lt;/TT &amp;gt;&lt;br /&gt;
To czarodziejskie zaklęcie rozwija się do paska nawigacji językowej dla artykułu [[Development/Tutorials]].  Uwaga: parametr wzorca &amp;lt;EM &amp;gt;nie zawiera&amp;lt;/EM &amp;gt; skrótu nazwy języka.&lt;br /&gt;
&lt;br /&gt;
{{translating|pl}}&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Help:Wiki_Translation</id>
		<title>Help:Wiki Translation</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Help:Wiki_Translation"/>
				<updated>2010-09-14T18:47:47Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Step 2: Create the Article */ &amp;quot;click&amp;quot; is mouse-centric&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Help:Wiki_Translation}}&lt;br /&gt;
This article describes how to '''translate articles into other languages'''. Please make sure to also read the last section called [[#Important Notes|important notes]].&lt;br /&gt;
&lt;br /&gt;
== Step 1: Language Abbreviations ==&lt;br /&gt;
&lt;br /&gt;
As an example let us assume you want to translate the following page to german:&lt;br /&gt;
* [[Development/Tutorials]]&lt;br /&gt;
The language abbreviation for german is '''de''', thus, all articles will have the ending &amp;quot; (de)&amp;quot; (with a leading space).&lt;br /&gt;
&lt;br /&gt;
Reference:  [http://translatewiki.net/wiki/Special:SupportedLanguages list of language abbreviations].&lt;br /&gt;
&lt;br /&gt;
== Step 2: Create the Article ==&lt;br /&gt;
&lt;br /&gt;
Sometimes a link in the language navigation bar already exists. In that case, simply [http://support.mozilla.com/en/kb/Browsing+basics#clicking_a_link follow the link] you want to translate. Otherwise, create the article manually:&lt;br /&gt;
* [[Development/Tutorials (de)]]&lt;br /&gt;
'''As initial content simply use the content of the corresponding english page'''. This way, no content is missing, and other readers can help with the translation.&lt;br /&gt;
&lt;br /&gt;
== Step 3: Language Navigation Bar ==&lt;br /&gt;
&lt;br /&gt;
The article must contain the following template line in order to show the language navigation bar:&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;{{Template:I18n/Language Navigation Bar|Development/Tutorials}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This magic line expands to the language navigation bar for the article &amp;lt;tt&amp;gt;Development/Tutorials&amp;lt;/tt&amp;gt;. Note, that the line does not contain the language abbreviation.&lt;br /&gt;
&lt;br /&gt;
== Step 4: Language Missing? ==&lt;br /&gt;
&lt;br /&gt;
If the language is missing, please search for the right abbreviation (see Step 1). In the example above this abbreviation is &amp;quot; (de)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Edit [[Template:I18n/Language Navigation Bar]] and add a line for the language you want to translate:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;span lang=&amp;quot;de&amp;quot;&amp;gt;[[{{{1}}}_(de)|Deutsch]]&amp;lt;/span&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Replace 'de' by the language abbreviation and adapt the visible name.&lt;br /&gt;
&lt;br /&gt;
== Important Notes ==&lt;br /&gt;
&lt;br /&gt;
As the wiki uses [[Help:Wiki Structure|subpages]] it is likely that translators run into the following issue.&lt;br /&gt;
&lt;br /&gt;
Assume the following pages exist:&lt;br /&gt;
 1. Development/Tutorials&lt;br /&gt;
 2. Development/Tutorials/Debugging&lt;br /&gt;
Further assume you want to translate (1) to german (postfix ''de'').&lt;br /&gt;
&lt;br /&gt;
The final page will be &lt;br /&gt;
 3. Development/Tutorials_(de)&lt;br /&gt;
The english content of (2) uses relative wiki links like &amp;lt;tt&amp;gt;/Debugging&amp;lt;/tt&amp;gt;. Translating ''Debugging'' in (3) might result in&lt;br /&gt;
 Development/Tutorials_(de)/Debugging      # wrong, or&lt;br /&gt;
 Development/Tutorials_(de)/Debugging_(de) # wrong&lt;br /&gt;
'''This is wrong.'''&lt;br /&gt;
&lt;br /&gt;
The rule of thumb is that the language abbreviation always appears at the very end of the article, that is the '''right link''' is supposed to be &lt;br /&gt;
 Development/Tutorials/Debugging_(de)&lt;br /&gt;
So be sure you adapt the links in the article to use absolute paths everywhere (i.e. no leading slash '/' in the wiki links).&lt;br /&gt;
&lt;br /&gt;
== Quality Assurance ==&lt;br /&gt;
&lt;br /&gt;
The system administrators and contributors try to keep a close watch at the content, but with foreign languages this is sometimes getting hard. It would be good, if you '''add yourself to the Watch list''' (just click ''Watch''). That way you will be noticed by mail whenever the article was changed. This will help to keep the wiki clean of e.g. spam, which unfortunately already happened.&lt;br /&gt;
&lt;br /&gt;
Also, consider to '''add yourself to the [[KDE_TechBase:Contributors#Translation_Teams|translation teams]]'''.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Help:Wiki_Translation_(pl)</id>
		<title>Help:Wiki Translation (pl)</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Help:Wiki_Translation_(pl)"/>
				<updated>2010-09-14T17:21:13Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Krok&amp;amp;nbsp;1: Skróty nazw języków */ Krok&amp;amp;nbsp;2.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Help:Wiki Translation}} &lt;br /&gt;
== Krok&amp;amp;nbsp;1.: Skróty nazw języków ==&lt;br /&gt;
&lt;br /&gt;
Przyjmijmy dla przykładu, że chcecie przetłumaczyć następującą stronę na polski:&lt;br /&gt;
* [[Development/Tutorials]]&lt;br /&gt;
Skrót nazwy języka polskiego to '''pl''', więc przetłumaczone artykuły mają nazwy kończące się na &amp;quot; (pl)&amp;quot; (z&amp;amp;nbsp;odstępem z&amp;amp;nbsp;przodu).&lt;br /&gt;
&lt;br /&gt;
Patrzcie:  [http://translatewiki.net/wiki/Special:SupportedLanguages spis nazw języków].&lt;br /&gt;
&lt;br /&gt;
== Krok&amp;amp;nbsp;2.: Tworzenie artykułu ==&lt;br /&gt;
&lt;br /&gt;
Nieraz potrzebny odnośnik istnieje już na pasku wyboru języka.  W&amp;amp;nbsp;tym wypadku po prostu wybierzcie odnośnik do strony tłumaczenia; inaczej utwórzcie tłumaczenie ręcznie:&lt;br /&gt;
* [[Development/Tutorials (pl)]]&lt;br /&gt;
'''Jako pierwotna zawartość tłumaczenia niech posłuży zawartość strony pierwotnej po angielsku.'''.  W&amp;amp;nbsp;ten sposób nie utracicie nic z&amp;amp;nbsp;zawartości.  Pamiętajcie, że inni użytkownicy również mogą pomóc w&amp;amp;nbsp;tłumaczeniu.&lt;br /&gt;
&lt;br /&gt;
{{translating|pl}}&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Help:Wiki_Translation</id>
		<title>Help:Wiki Translation</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Help:Wiki_Translation"/>
				<updated>2010-09-14T17:14:09Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Step 1: Language Abbreviations */ a better list&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Help:Wiki_Translation}}&lt;br /&gt;
This article describes how to '''translate articles into other languages'''. Please make sure to also read the last section called [[#Important Notes|important notes]].&lt;br /&gt;
&lt;br /&gt;
== Step 1: Language Abbreviations ==&lt;br /&gt;
&lt;br /&gt;
As an example let us assume you want to translate the following page to german:&lt;br /&gt;
* [[Development/Tutorials]]&lt;br /&gt;
The language abbreviation for german is '''de''', thus, all articles will have the ending &amp;quot; (de)&amp;quot; (with a leading space).&lt;br /&gt;
&lt;br /&gt;
Reference:  [http://translatewiki.net/wiki/Special:SupportedLanguages list of language abbreviations].&lt;br /&gt;
&lt;br /&gt;
== Step 2: Create the Article ==&lt;br /&gt;
&lt;br /&gt;
Sometimes a link in the language navigation bar already exists. In that case, simply click on the link you want to translate. Otherwise, create the article manually:&lt;br /&gt;
* [[Development/Tutorials (de)]]&lt;br /&gt;
'''As initial content simply use the content of the corresponding english page'''. This way, no content is missing, and other readers can help with the translation.&lt;br /&gt;
&lt;br /&gt;
== Step 3: Language Navigation Bar ==&lt;br /&gt;
&lt;br /&gt;
The article must contain the following template line in order to show the language navigation bar:&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;{{Template:I18n/Language Navigation Bar|Development/Tutorials}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This magic line expands to the language navigation bar for the article &amp;lt;tt&amp;gt;Development/Tutorials&amp;lt;/tt&amp;gt;. Note, that the line does not contain the language abbreviation.&lt;br /&gt;
&lt;br /&gt;
== Step 4: Language Missing? ==&lt;br /&gt;
&lt;br /&gt;
If the language is missing, please search for the right abbreviation (see Step 1). In the example above this abbreviation is &amp;quot; (de)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Edit [[Template:I18n/Language Navigation Bar]] and add a line for the language you want to translate:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;span lang=&amp;quot;de&amp;quot;&amp;gt;[[{{{1}}}_(de)|Deutsch]]&amp;lt;/span&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Replace 'de' by the language abbreviation and adapt the visible name.&lt;br /&gt;
&lt;br /&gt;
== Important Notes ==&lt;br /&gt;
&lt;br /&gt;
As the wiki uses [[Help:Wiki Structure|subpages]] it is likely that translators run into the following issue.&lt;br /&gt;
&lt;br /&gt;
Assume the following pages exist:&lt;br /&gt;
 1. Development/Tutorials&lt;br /&gt;
 2. Development/Tutorials/Debugging&lt;br /&gt;
Further assume you want to translate (1) to german (postfix ''de'').&lt;br /&gt;
&lt;br /&gt;
The final page will be &lt;br /&gt;
 3. Development/Tutorials_(de)&lt;br /&gt;
The english content of (2) uses relative wiki links like &amp;lt;tt&amp;gt;/Debugging&amp;lt;/tt&amp;gt;. Translating ''Debugging'' in (3) might result in&lt;br /&gt;
 Development/Tutorials_(de)/Debugging      # wrong, or&lt;br /&gt;
 Development/Tutorials_(de)/Debugging_(de) # wrong&lt;br /&gt;
'''This is wrong.'''&lt;br /&gt;
&lt;br /&gt;
The rule of thumb is that the language abbreviation always appears at the very end of the article, that is the '''right link''' is supposed to be &lt;br /&gt;
 Development/Tutorials/Debugging_(de)&lt;br /&gt;
So be sure you adapt the links in the article to use absolute paths everywhere (i.e. no leading slash '/' in the wiki links).&lt;br /&gt;
&lt;br /&gt;
== Quality Assurance ==&lt;br /&gt;
&lt;br /&gt;
The system administrators and contributors try to keep a close watch at the content, but with foreign languages this is sometimes getting hard. It would be good, if you '''add yourself to the Watch list''' (just click ''Watch''). That way you will be noticed by mail whenever the article was changed. This will help to keep the wiki clean of e.g. spam, which unfortunately already happened.&lt;br /&gt;
&lt;br /&gt;
Also, consider to '''add yourself to the [[KDE_TechBase:Contributors#Translation_Teams|translation teams]]'''.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Help:Wiki_Translation_(pl)</id>
		<title>Help:Wiki Translation (pl)</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Help:Wiki_Translation_(pl)"/>
				<updated>2010-09-14T17:11:37Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Krok&amp;amp;nbsp;1: Skróty nazw języków */ spis nazw&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Help:Wiki Translation}} &lt;br /&gt;
== Krok&amp;amp;nbsp;1: Skróty nazw języków ==&lt;br /&gt;
&lt;br /&gt;
Przyjmijmy dla przykładu, że chcecie przetłumaczyć następującą stronę na polski:&lt;br /&gt;
* [[Development/Tutorials]]&lt;br /&gt;
Skrót nazwy języka polskiego to '''pl''', więc przetłumaczone artykuły mają nazwy kończące się na &amp;quot; (pl)&amp;quot; (z&amp;amp;nbsp;odstępem z&amp;amp;nbsp;przodu).&lt;br /&gt;
&lt;br /&gt;
Patrzcie:  [http://translatewiki.net/wiki/Special:SupportedLanguages spis nazw języków].&lt;br /&gt;
{{translating|pl}}&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Help:Wiki_Translation_(pl)</id>
		<title>Help:Wiki Translation (pl)</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Help:Wiki_Translation_(pl)"/>
				<updated>2010-09-14T16:45:27Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: translation stub&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Help:Wiki Translation}} &lt;br /&gt;
== Krok&amp;amp;nbsp;1: Skróty nazw języków ==&lt;br /&gt;
&lt;br /&gt;
Przyjmijmy dla przykładu, że chcecie przetłumaczyć następującą stronę na polski:&lt;br /&gt;
* [[Development/Tutorials]]&lt;br /&gt;
Skrót nazwy języka polskiego to '''pl''', więc przetłumaczone artykuły mają nazwy kończące się na &amp;quot; (pl)&amp;quot; (z&amp;amp;nbsp;odstępem z&amp;amp;nbsp;przodu).&lt;br /&gt;
&lt;br /&gt;
Patrzcie:  [http://www.opticentre.net/FAQ/Languages/List-of-language-abbreviations/ spis nazw języków].&lt;br /&gt;
{{translating|pl}}&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Template:Translating/pl</id>
		<title>Template:Translating/pl</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Template:Translating/pl"/>
				<updated>2010-09-14T16:41:30Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: plural&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Strona w&amp;amp;nbsp;trakcie tłumaczenia.  Rzetelne informacje są w&amp;amp;nbsp;oryginale angielskim.  Pomóżcie tłumaczyć.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Template:Translating</id>
		<title>Template:Translating</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Template:Translating"/>
				<updated>2010-09-14T16:37:42Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: includeonly&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;&amp;lt;P STYLE=&amp;quot;TEXT-ALIGN: CENTER; BORDER: MEDIUM SOLID BLUE; PADDING: 2PX; FONT-WEIGHT: BOLDER&amp;quot; &amp;gt;&lt;br /&gt;
{{translating/{{{1}}}}}&amp;lt;/P &amp;gt;&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Template:Translating</id>
		<title>Template:Translating</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Template:Translating"/>
				<updated>2010-09-14T16:34:05Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: parametrize by language&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;P STYLE=&amp;quot;TEXT-ALIGN: CENTER; BORDER: MEDIUM SOLID BLUE; PADDING: 2PX; FONT-WEIGHT: BOLDER&amp;quot; &amp;gt;&lt;br /&gt;
{{translating/{{{1}}}}}&amp;lt;/P &amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Template:Translating</id>
		<title>Template:Translating</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Template:Translating"/>
				<updated>2010-09-14T16:31:09Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: created&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;P STYLE=&amp;quot;TEXT-ALIGN: CENTER; BORDER: MEDIUM SOLID BLUE; PADDING: 2PX; FONT-WEIGHT: BOLDER&amp;quot; &amp;gt;&lt;br /&gt;
{{translating/en}}&amp;lt;/P &amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Template:Translating/pl</id>
		<title>Template:Translating/pl</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Template:Translating/pl"/>
				<updated>2010-09-14T16:29:24Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: created&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Strona w&amp;amp;nbsp;trakcie tłumaczenia.  Rzetelne informacje są w&amp;amp;nbsp;oryginale angielskim.  Pomóż tłumaczyć.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Template:Translating/en</id>
		<title>Template:Translating/en</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Template:Translating/en"/>
				<updated>2010-09-14T16:27:00Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: created&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Page under translation.  Please use the English version for reference.  Please help.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/MediaWiki_talk:Projects/pl</id>
		<title>MediaWiki talk:Projects/pl</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/MediaWiki_talk:Projects/pl"/>
				<updated>2010-09-14T16:09:26Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: Projekty&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Projekty ==&lt;br /&gt;
&lt;br /&gt;
--[[User:Yecril71pl|Yecril71pl]] 16:09, 14 September 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/MediaWiki_talk:Contribute/pl</id>
		<title>MediaWiki talk:Contribute/pl</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/MediaWiki_talk:Contribute/pl"/>
				<updated>2010-09-14T16:08:46Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: Dołącz&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Dołącz ==&lt;br /&gt;
&lt;br /&gt;
--[[User:Yecril71pl|Yecril71pl]] 16:08, 14 September 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/MediaWiki_talk:Policies/pl</id>
		<title>MediaWiki talk:Policies/pl</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/MediaWiki_talk:Policies/pl"/>
				<updated>2010-09-14T16:07:52Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: Zasady&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Zasady ==&lt;br /&gt;
&lt;br /&gt;
--[[User:Yecril71pl|Yecril71pl]] 16:07, 14 September 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/MediaWiki_talk:Schedules/pl</id>
		<title>MediaWiki talk:Schedules/pl</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/MediaWiki_talk:Schedules/pl"/>
				<updated>2010-09-14T16:07:20Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: Rozkłady&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Rozkłady ==&lt;br /&gt;
&lt;br /&gt;
--[[User:Yecril71pl|Yecril71pl]] 16:07, 14 September 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/User_talk:Yecril71pl</id>
		<title>User talk:Yecril71pl</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/User_talk:Yecril71pl"/>
				<updated>2010-09-14T16:05:28Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: Sidebar&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Sidebar ==&lt;br /&gt;
&lt;br /&gt;
[[MediaWiki:Sidebar]] is not fully translated into Polish.  The translated messages should land in MediaWiki:''message''/pl.  Since only [[Project:Administrators]] can edit those messages, I am placing the text into the talk pages.&lt;br /&gt;
&lt;br /&gt;
* [[MediaWiki:navigation/pl]]&lt;br /&gt;
** mainpage|[[MediaWiki:Home/pl]]&lt;br /&gt;
** helppage|[[MediaWiki:help/pl]]&lt;br /&gt;
** recentchanges-url|[[MediaWiki:recentchanges/pl]]&lt;br /&gt;
&lt;br /&gt;
* [[MediaWiki:Sections/pl]]&lt;br /&gt;
** Getting_Started|[[MediaWiki:Getting started/pl]]&lt;br /&gt;
** Development|[[MediaWiki:Development/pl]]&lt;br /&gt;
** Schedules|[[MediaWiki:Schedules/pl]]&lt;br /&gt;
** Policies|[[MediaWiki:Policies/pl]]&lt;br /&gt;
** Contribute|[[MediaWiki:Contribute/pl]]&lt;br /&gt;
** Projects|[[MediaWiki:Projects/pl]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[User:Yecril71pl|Yecril71pl]] 16:05, 14 September 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/KDE_TechBase:Administrators</id>
		<title>KDE TechBase:Administrators</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/KDE_TechBase:Administrators"/>
				<updated>2010-09-14T16:00:33Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: +fragment id&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[KDE TechBase:Contributors#Administrators]]&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/MediaWiki_talk:Development/pl</id>
		<title>MediaWiki talk:Development/pl</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/MediaWiki_talk:Development/pl"/>
				<updated>2010-09-14T15:50:22Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: Rozwój&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Rozwój ==&lt;br /&gt;
&lt;br /&gt;
--[[User:Yecril71pl|Yecril71pl]] 15:50, 14 September 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/MediaWiki_talk:Getting_started/pl</id>
		<title>MediaWiki talk:Getting started/pl</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/MediaWiki_talk:Getting_started/pl"/>
				<updated>2010-09-14T15:49:28Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: Jak zacząć&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Jak zacząć ==&lt;br /&gt;
&lt;br /&gt;
--[[User:Yecril71pl|Yecril71pl]] 15:49, 14 September 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/MediaWiki_talk:Sections/pl</id>
		<title>MediaWiki talk:Sections/pl</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/MediaWiki_talk:Sections/pl"/>
				<updated>2010-09-14T15:48:23Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: Działy&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Działy ==&lt;br /&gt;
&lt;br /&gt;
--[[User:Yecril71pl|Yecril71pl]] 15:48, 14 September 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/MediaWiki_talk:Home/pl</id>
		<title>MediaWiki talk:Home/pl</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/MediaWiki_talk:Home/pl"/>
				<updated>2010-09-14T15:47:26Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: Strona główna&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Strona główna ==&lt;br /&gt;
&lt;br /&gt;
--[[User:Yecril71pl|Yecril71pl]] 15:47, 14 September 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/MediaWiki_talk:Sitenotice</id>
		<title>MediaWiki talk:Sitenotice</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/MediaWiki_talk:Sitenotice"/>
				<updated>2010-09-14T15:42:18Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: Interlink please&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Interlink please ==&lt;br /&gt;
&lt;br /&gt;
I would say that TechBase is a [http://www.mediawiki.org/ Wiki].&lt;br /&gt;
--[[User:Yecril71pl|Yecril71pl]] 15:42, 14 September 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/User_talk:Danimo</id>
		<title>User talk:Danimo</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/User_talk:Danimo"/>
				<updated>2010-09-14T15:03:17Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Wiki software revealed */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==CAPTCHAs that won't go away==&lt;br /&gt;
Aseigo [[Talk:Main_Page#Something_wrong_with_the_CAPTCHAs|suggested]] that I ask you about this.  Everytime I make an edit, it claims that I am adding a URL, and wants me to do some math.  Is it even supposed to do this to registered users?  In any case, ''most'' times I am not adding a url at all, and I tire of the systems inordinate appetite for elementary arithmetic.  Can this be fixed?  Thanks. --[[User:Axiom|Axiom]] 20:27, 28 March 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;nowiki&amp;gt;{{file}}&amp;lt;/nowiki&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
As you asked me, I removed all the occurrences of &amp;lt;nowiki&amp;gt;{{file}}&amp;lt;/nowiki&amp;gt; with &amp;lt;nowiki&amp;gt;{{path}}&amp;lt;/nowiki&amp;gt;, and removed the obsolete template &amp;lt;nowiki&amp;gt;{{file}}&amp;lt;/nowiki&amp;gt;. -- [[user:Pino|pino]] 02:16, 29 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
:There is also a template called &amp;lt;nowiki&amp;gt;{{module}}&amp;lt;/nowiki&amp;gt; for KDE modules (kdelibs, kdebase), etc. I initially used path here, too, and thought that's enough. It's not widely used, only by 2 articles. Maybe we should replace it by path again? What do you think? --[[User:Dhaumann|Dhaumann]] 09:14, 29 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
::I agree. --[[User:Danimo|Danimo]] 09:28, 29 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
::Or maybe link it to the module page in the apidocs (e.g [http://api.kde.org/4.0-api/kdelibs-apidocs/ kdelibs])? --[[User:Milliams|milliams]] 14:47, 29 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
:::Good idea, &amp;lt;nowiki&amp;gt;{{kdelibs}}, {{kdebase}}&amp;lt;/nowiki&amp;gt; etc... +1 from my side :) --[[User:Dhaumann|Dhaumann]] 15:11, 29 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
::::Sounds good. Or how about &amp;lt;nowiki&amp;gt;{{module|foo}}&amp;lt;/nowiki&amp;gt; linking to http://api.kde.org/4.0-api/foo-apidocs/? I don't know how flexible this method is though? --[[User:Milliams|milliams]] 19:41, 29 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
:::::+1 on [[User:Milliams|milliams]]' idea --[[user:Pino|pino]] 21:35, 29 May 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Assistance needed for new contributor to Techbase==&lt;br /&gt;
Hi. My name is Thor, I am a new contributor to KDE and I am looking to provide some help with regard to one of the KDE Games, KTuberling (The Potato dude).  I am a Polyglot, and work in many different languages, and I have noticed on issues of KTuberling that even with correct software in place, certain speech selections do not function (Notably; Serbian and Danish).  I have been working on these for a while and would like to obtain source code for the Tuberling to try and correct the error.  Could you tell me please how I find out who is working on what, and what they are doing to it?  Thanks and Regards.  [[User:ThunderGod|ThunderGod]] 15:40, 30 December 2007 (CET)&lt;br /&gt;
:The best place to find assistance with this is by visiting the #kdegames or #kde-edu channels on irc.freenode.org or by sending an joining the KDE Games mailing list at [https://mail.kde.org/mailman/listinfo/kde-games-devel https://mail.kde.org/mailman/listinfo/kde-games-devel]. I believe tsdgeos (Albert Astals Cid) is the best person to speak to. --[[User:Milliams|milliams]] 17:13, 30 December 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
== More readable URLs ==&lt;br /&gt;
&lt;br /&gt;
At the moment all links on this site are in the form [http://techbase.kde.org/index.php?title=Development/Tutorials http://techbase.kde.org/index.php?title=Development/Tutorials]. I think it would make the site much more readable to convert these links into something like [http://techbase.kde.org/Development/Tutorials http://techbase.kde.org/Development/Tutorials]. Now, as you can see, if you click on that link it does indeed work and takes you to the same page (so you've obviously got mod_rewrite working correctly) so the problem is that mediawiki itself isn't formatting it's links to take advantage of this. I think you basically need to do step 2 from [http://www.mediawiki.org/wiki/Manual:Short_URL#Setup_steps here]. --[[User:Milliams|milliams]] 14:53, 18 April 2008 (CEST)&lt;br /&gt;
:It seems this is working now. Thanks a lot :) --[[User:Milliams|milliams]] 14:34, 28 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Remove my account ==&lt;br /&gt;
&lt;br /&gt;
Please remove my account; i'd like to choose another username. Thank you. [[User:Krf|KRF]]&lt;br /&gt;
&lt;br /&gt;
:Mediawiki has no concept of user account deletion, since that would mess up the history. Just create a new user and add redirects from your current user accounts user page. --[[User:Danimo|Danimo]] 17:55, 20 April 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
Okay, would be nice if you could make my username uppercase then... Some database tweaking maybe? ;). No need to answer this, you can remove my entry when you've read it. Thank you anyway. [[User:Krf|KRF]]&lt;br /&gt;
&lt;br /&gt;
== Hidden search button text in french localized ktechbase==&lt;br /&gt;
&lt;br /&gt;
When switching ktechbase language to french the button search text is really too small. I have read somewhere that the css file will use fixed width for a while so changing the search button width from 4em to 6em will fix that small issue.&lt;br /&gt;
&lt;br /&gt;
== The problem with images in article ==&lt;br /&gt;
&lt;br /&gt;
When adding the existing image file i can't save the whole article.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Article: http://techbase.kde.org/Projects/Plasma/Plasmoids_(ru)&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Adding image (ex. kickoff.png), typing the code, saving and got &amp;quot;http://techbase.kde.org/index.php?title=Projects/Plasma/Plasmoids_(ru)&amp;amp;amp;action=submit&amp;quot; and&amp;amp;nbsp; a blank page. When i reload a page, i've got old text back, without any changes. Using Firefox 3.0. Can save only the text. What can we do about it? Thanks.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Where can I post a patch? ==&lt;br /&gt;
&lt;br /&gt;
My article on building the dependencies for KDE-4.x:&lt;br /&gt;
&lt;br /&gt;
http://techbase.kde.org/Getting_Started/Build/KDE4/LFS#QCA-2.0.2_.28crypto_add_on_for_Qt.29&lt;br /&gt;
&lt;br /&gt;
requires a patch for a file that will not build.  Is there somewhere on the TechBase site where I can post this?  Currently it is linked to my private web site and I would rather not have that.&lt;br /&gt;
&lt;br /&gt;
[[User:JRT|JRT]] 10:56, 13 September 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Wiki software revealed ==&lt;br /&gt;
&lt;br /&gt;
=== Powered by please ===&lt;br /&gt;
It would be nice to reveal the software used in the [http://www.mediawiki.org/wiki/Manual:Footer page footer]. [http://techbase.kde.org/skins/common/images/poweredby_mediawiki_88x31.png (with this image)]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;P STYLE=&amp;quot;TEXT-ALIGN: RIGHT&amp;quot; &amp;gt;[http://www.mediawiki.org/wiki/MediaWiki Powered by MediaWiki]&lt;br /&gt;
&lt;br /&gt;
=== Database configuration bug ===&lt;br /&gt;
See e.g. &amp;amp;lt;URL:{{fullurl:złocień}}&amp;gt;:&lt;br /&gt;
&amp;lt;BLOCKQUOTE &amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h4 STYLE=&amp;quot;COLOR: BLACK&amp;quot; &amp;gt;Database error&amp;lt;/h4&amp;gt;&lt;br /&gt;
		A database query syntax error has occurred.&lt;br /&gt;
This may indicate a bug in the software.&lt;br /&gt;
The last attempted database query was:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;tt&amp;gt;(SQL query hidden)&amp;lt;/tt&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
from within function &amp;quot;&amp;lt;tt&amp;gt;Article::pageData&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
MySQL returned error &amp;quot;&amp;lt;tt&amp;gt;1267: Illegal mix of collations (latin1_bin,IMPLICIT) and (utf8_unicode_ci,COERCIBLE) for operation '=' (localhost)&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/BLOCKQUOTE &amp;gt;&lt;br /&gt;
&lt;br /&gt;
This should never happen, compare &amp;amp;lt;URL:http://www.mediawiki.org/wiki/Z%C5%82ocie%C5%84&amp;gt;.  This problem will prevents Wiki for having non-Western-European page names in translations.  The most probable cause is a misconfiguration of the database engine; however, it is also worth noting that the current MediaWiki software is [http://lists.wikimedia.org/pipermail/mediawiki-announce/2010-July/000092.html 1.16] whereas you are using 1.14 (from HTML metadata, otherwise unmentioned), so maybe it would be time to upgrade?&lt;br /&gt;
&lt;br /&gt;
--[[User:Yecril71pl|Yecril71pl]] 15:03, 14 September 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy</id>
		<title>KDE System Administration/KDE Filesystem Hierarchy</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy"/>
				<updated>2010-09-14T13:07:29Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Adding Lookup Locations */ fix ref&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|KDE_System_Administration/KDE_Filesystem_Hierarchy}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
KDE defines a filesystem hierarchy that is used by the KDE environment&lt;br /&gt;
itself as well as all KDE applications. In general, KDE stores all its&lt;br /&gt;
files in a fixed directory tree.&lt;br /&gt;
&lt;br /&gt;
By default, there are two such directory trees: one at the system&lt;br /&gt;
level and one at the user level in the user's home directory. However,&lt;br /&gt;
as a system administrator you can create additional trees.&lt;br /&gt;
&lt;br /&gt;
KDE and KDE applications look up files by scanning the directory trees&lt;br /&gt;
in order of precedence. When a file is&lt;br /&gt;
present in multiple directory trees, the file from the first-listed&lt;br /&gt;
tree takes precedence.&lt;br /&gt;
Normally, the tree located in the user's home directory has the highest&lt;br /&gt;
precedence. This is also the directory tree that changes are&lt;br /&gt;
written to.&lt;br /&gt;
&lt;br /&gt;
For configuration files, the story is slightly&lt;br /&gt;
different. If multiple configuration files with the same name are found in the directory&lt;br /&gt;
trees, their content is combined. The precedence order&lt;br /&gt;
of the directory trees plays a role here: when two files define the same&lt;br /&gt;
configuration key, the file with the highest precedence determines which&lt;br /&gt;
value is used for the key.&lt;br /&gt;
&lt;br /&gt;
== Location of the Directory Trees ==&lt;br /&gt;
&lt;br /&gt;
The location of the KDE Directory Trees is determined by a number of&lt;br /&gt;
environment variables, each of which is covered below.&lt;br /&gt;
&lt;br /&gt;
=== KDEHOME ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;KDEHOME&amp;lt;/tt&amp;gt; environment variable determines the location of the user-level&lt;br /&gt;
directory tree and is used by KDE applications for creating and saving&lt;br /&gt;
files. This directory tree has the highest precedence; files or settings&lt;br /&gt;
found in this directory tree will take precedence over any files or settings&lt;br /&gt;
found in other directory trees.&lt;br /&gt;
&lt;br /&gt;
This directory tree is, as the name suggests, normally located in the user's home directory. If this environment variable is not defined, the default location &amp;lt;tt&amp;gt;$HOME/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; is used.&lt;br /&gt;
&lt;br /&gt;
If the environment variable has a value that starts with a tilde (~), the tilde is replaced with the user's home directory at runtime. In order to use this, care must be taken to add proper quoting, otherwise the shell might do the expansion, resulting in undesired behavior in combination with &amp;lt;tt&amp;gt;su&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== KDEROOTHOME ===&lt;br /&gt;
In order to prevent problems with applications that run as root saving&lt;br /&gt;
files with root access permissions in the user's home directory, the &amp;lt;tt&amp;gt;KDEROOTHOME&amp;lt;/tt&amp;gt;&lt;br /&gt;
environment variable has been introduced in the KDE 3.x series. Applications&lt;br /&gt;
that run with uid 0 (root) will use this variable to determine the location of&lt;br /&gt;
the user level directory and where to save their files. If this variable is&lt;br /&gt;
not defined, the root user's home directory is looked up in the password&lt;br /&gt;
file and .kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt; is appended. Usually that results in &amp;lt;tt&amp;gt;/root/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== KDEDIRS ===&lt;br /&gt;
It is possible to specify multiple system-level directory trees. This allows groups of users to each dedicate a directory to their group. Such an additional directory tree can contain additional applications, specialized application resources or a specific set of default configurations suitable for the group. Specifying default configurations this way instead of using a /etc/skel construction has the advantage that changes in the default configuration can be made after the user's account has been created.&lt;br /&gt;
&lt;br /&gt;
The directories in $KDEDIRS should be separated with a colon (:). The directories are listed in order of precedence: the first directory has the highest precedence, the last one has the lowest precedence.&lt;br /&gt;
&lt;br /&gt;
Since a group-level directory tree should normally override any settings present at the system level, one should list the group-level directory tree before the system level directory tree.&lt;br /&gt;
&lt;br /&gt;
In general communication, references to the directory trees are made in&lt;br /&gt;
terms of $KDEHOME to indicate the applicable user-level directory tree,&lt;br /&gt;
and in terms of $KDEDIRS to indicate any of the system-level directory trees.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
A staff member at a university could have the following settings:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEROOTHOME='/root/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the user settings are saved under the .kde3 directory&lt;br /&gt;
in the user's home directory. Applications that run as root will save their&lt;br /&gt;
settings to /root/.kde3. KDE 3 has been installed to /opt/kde3 but there is&lt;br /&gt;
also an additional directory tree located at /opt/kde_staff. Configuration&lt;br /&gt;
files under that directory will take precedence over the ones in the /opt/kde3&lt;br /&gt;
system directories. /opt/kde_staff could contain additional applications that&lt;br /&gt;
should only be available to staff members.&lt;br /&gt;
&lt;br /&gt;
== Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
Each directory tree used by KDE has a fixed directory structure. However, directories&lt;br /&gt;
that are not relevant for a certain tree can be left out. For example,&lt;br /&gt;
directories used for temporary files are usually only found under $KDEHOME but&lt;br /&gt;
not in any other directory tree.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The KDE runtime environment combines the subdirectories found under the&lt;br /&gt;
various directory trees and refers to them as a single KDE resource. The&lt;br /&gt;
KDE resource name is listed in the tables below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are three broad categories: files that are&lt;br /&gt;
CPU/architecture-specific, files that are host-specific and files that are not specific with&lt;br /&gt;
regard to host, CPU or architecture.&lt;br /&gt;
&lt;br /&gt;
CPU/architecture-specific directories:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|bin/}} || exe || Used for KDE executables.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cgi-bin/}} || cgi || CGI scipts that can be used by the KDE Help Center.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || lib || Used for KDE libraries.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/kde&amp;lt;sub &amp;gt;3&amp;lt;var &amp;gt;&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || module || This directory contains components, plugins and other runtime loadable objects for use by KDE 3.x applications.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following are host-specific directories. They are only available under&lt;br /&gt;
$KDEHOME and are normally symlinked to locations outside the $KDEHOME&lt;br /&gt;
directory tree.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|socket-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Sockets|socket]] || This directory contains communication sockets. The filesystem used by $KDEHOME may not be suitable for communication sockets. For that reason this directory is symlinked to another location by default.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|tmp-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Temporary Files|tmp]] || This directory is used for temporary files. The filesystem used by $KDEHOME may be on a network, so, for performance reasons, this directory is symlinked by default to a location more likely to be on a local filesystem.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cache-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Cache Files|cache]] || New in KDE 3.2. This directory is used for cached information such as HTTP objects, formatted help pages and the system configuration cache (ksycoca).&lt;br /&gt;
&lt;br /&gt;
Since this is non-essential information, this directory is&lt;br /&gt;
symlinked to a location outside $KDEHOME by default to make it easier&lt;br /&gt;
to make backups of other information and reclaim diskspace.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The majority of directories involves data that is not CPU-, architecture- or&lt;br /&gt;
host-specific. All these directories are prefixed with {{path|share/}}:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/applnk/}} || apps || Contains .desktop files describing the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/apps/}} || data || Contains application-specific data files. Each application has a subdirectory here for storing its files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/}} || config || Contains configuration files. Configuration files are normally named after the application they belong to, followed by &amp;quot;rc&amp;quot;. There are also files that are specific to a component and as such referenced by all applications that use that component. A special case is &amp;quot;kdeglobals&amp;quot;: this file is read by all KDE applications.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/session/}} || - || This directory is used by session management and is normally only available under $KDEHOME. At the end of a session, KDE applications store their state here. The file names start with the name of the application followed by a number. The session manager &amp;quot;ksmserver&amp;quot; stores references to these numbers when saving a session in &amp;quot;ksmserverrc&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/doc/HTML/}} || html || Documentation of KDE applications is stored here. Documentation is categorized by language and the application it belongs to. &lt;br /&gt;
&lt;br /&gt;
Normally, at least two files can be found in a directory: &amp;quot;index.docbook&amp;quot;, which contains the documentation in the unformatted docbook format, and &amp;quot;index.cache.bz2&amp;quot;, which contains the same documentation formatted as bzip2 compressed HTML. The HTML version is used by khelpcenter; if the HTML version is missing, it will regenerate it from the docbook version, but this is a time-consuming process.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/icons/}} || icon || Icons are stored under this directory, categorized by theme, dimension and usage category.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mimelnk/}} || mime || Up until KDE4, .desktop files that describe MIME types were stored in this directory.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mime/}} || mime || Starting with KDE4, desktop files that describe MIME types are stored in this directory. This data is shared by other software as well and is part of a freedesktop.org specification.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/services/}}&amp;lt;br&amp;gt;{{path|share/kde4/services/}} || services || This directory contains .desktop files that describe services. Services and Applications are very similar; the major difference is that a Service is usually used by other Services or Applications, while an Application is in general started by the user. Services do not appear in the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/servicetypes/}}&amp;lt;br&amp;gt;{{path|share/kde4/servicetypes/}} || servicetypes || This directory contains .desktop files that describe service types. A service type usually represents a certain programming interface. Applications and Services include the servicetypes that they provide in their .desktop files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/sounds/}} || sound || This directory contains sound files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/templates/}} || templates || This directory contains templates for creating files of various types. A template consists of a .desktop file that describes the file and includes a reference to a file in the .source subdirectory. The templates in this directory appear in the &amp;quot;Create New&amp;quot; menu available on the desktop and in the file browser. When a user selects a template from the menu, its source file is copied.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/wallpapers/}} || wallpaper || This directory contains images that can be used as background pictures.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Outside the Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
As mentioned in the description of the directory tree, there are three host-specific directories that are usually symlinked to other locations. If the directories do not already exist, the following symlinks and directories will be created using the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility. Since both &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt; are world writable, there is a possibility that one of the mentioned directories already exists but is owned by another user. In that case, the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility will create a new directory with an alternative name and link to that instead.&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/socket-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/ksocket-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
The command &amp;lt;tt&amp;gt;lnusertemp socket&amp;lt;/tt&amp;gt; creates a directory for local communication sockets and point a symlink to it. The combined length of the directory name and the name of any communication socket should not exceed 106 characters. By default this directory is created under &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt;, but other locations can be used by setting the KDETMP environment variable.&lt;br /&gt;
&lt;br /&gt;
=== Temporary Files ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/tmp-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/kde-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
The command &amp;lt;tt&amp;gt;lnusertemp tmp&amp;lt;/tt&amp;gt; creates a directory for temporary files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
=== Cache Files ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/cache-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
 &lt;br /&gt;
Default destination: {{path|/var/tmp/kdecache-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
The command &amp;lt;tt&amp;gt;lnusertemp cache&amp;lt;/tt&amp;gt; creates a directory for cache files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
The system configuration cache (&amp;lt;tt &amp;gt;ksycoca&amp;lt;/tt &amp;gt; and &amp;lt;tt &amp;gt;ksycocastamp&amp;lt;/tt &amp;gt;) is located in here. It is recommended NOT to delete these files during boot since that will slow down the startup of KDE.&lt;br /&gt;
&lt;br /&gt;
By default this directory is created under &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt;, other locations&lt;br /&gt;
can be used by setting the KDEVARTMP environment variable.&lt;br /&gt;
&lt;br /&gt;
== Adding Lookup Locations ==&lt;br /&gt;
&lt;br /&gt;
KDE applications look up data files using the resource names listed in the&lt;br /&gt;
[[#Directory Tree]] section.  The KDE runtime&lt;br /&gt;
environment translates these names to actual directories&lt;br /&gt;
by combining the locations of the directory trees with the directories&lt;br /&gt;
listed in the tables.&lt;br /&gt;
&lt;br /&gt;
==== Defining Search Paths ====&lt;br /&gt;
&lt;br /&gt;
A user has the following directory tree settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an application now looks for a &amp;quot;wallpaper&amp;quot; file, the directory {{path|share/wallpapers/}} is added to each of the&lt;br /&gt;
directory trees. All of the&lt;br /&gt;
resulting directories are then searched for the file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By adding more directory tree to the KDEDIRS environment variable&lt;br /&gt;
it is possible to expand the number of directories that are being searched.&lt;br /&gt;
Sometimes it is desirable to include only a single directory in a search&lt;br /&gt;
but not a whole directory tree. Additional directories can be configured&lt;br /&gt;
in the &amp;lt;TT &amp;gt;kdeglobals&amp;lt;/TT &amp;gt; configuration file in the &amp;lt;TT &amp;gt;[Directories]&amp;lt;/TT &amp;gt; section.&lt;br /&gt;
To do so assign one or more directories to the key &amp;lt;TT &amp;gt;dir_&amp;lt;/TT &amp;gt; followed by the&lt;br /&gt;
name of the resource. &lt;br /&gt;
Multiple directories are separated by commas (&amp;lt;TT &amp;gt;,&amp;lt;/TT &amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==== Adding a Resource Directory ====&lt;br /&gt;
&lt;br /&gt;
To add the directory {{path|/data/photos}} to the wallpaper resource, put the&lt;br /&gt;
following two lines in &amp;lt;TT &amp;gt;kdeglobals&amp;lt;/TT &amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Directories]&lt;br /&gt;
dir_wallpaper=/data/photos&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the application now looks for wallpaper files, it will look in the&lt;br /&gt;
following locations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
/data/photos&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy</id>
		<title>KDE System Administration/KDE Filesystem Hierarchy</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy"/>
				<updated>2010-09-14T12:59:40Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Sockets */ will not run with nbsp&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|KDE_System_Administration/KDE_Filesystem_Hierarchy}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
KDE defines a filesystem hierarchy that is used by the KDE environment&lt;br /&gt;
itself as well as all KDE applications. In general, KDE stores all its&lt;br /&gt;
files in a fixed directory tree.&lt;br /&gt;
&lt;br /&gt;
By default, there are two such directory trees: one at the system&lt;br /&gt;
level and one at the user level in the user's home directory. However,&lt;br /&gt;
as a system administrator you can create additional trees.&lt;br /&gt;
&lt;br /&gt;
KDE and KDE applications look up files by scanning the directory trees&lt;br /&gt;
in order of precedence. When a file is&lt;br /&gt;
present in multiple directory trees, the file from the first-listed&lt;br /&gt;
tree takes precedence.&lt;br /&gt;
Normally, the tree located in the user's home directory has the highest&lt;br /&gt;
precedence. This is also the directory tree that changes are&lt;br /&gt;
written to.&lt;br /&gt;
&lt;br /&gt;
For configuration files, the story is slightly&lt;br /&gt;
different. If multiple configuration files with the same name are found in the directory&lt;br /&gt;
trees, their content is combined. The precedence order&lt;br /&gt;
of the directory trees plays a role here: when two files define the same&lt;br /&gt;
configuration key, the file with the highest precedence determines which&lt;br /&gt;
value is used for the key.&lt;br /&gt;
&lt;br /&gt;
== Location of the Directory Trees ==&lt;br /&gt;
&lt;br /&gt;
The location of the KDE Directory Trees is determined by a number of&lt;br /&gt;
environment variables, each of which is covered below.&lt;br /&gt;
&lt;br /&gt;
=== KDEHOME ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;KDEHOME&amp;lt;/tt&amp;gt; environment variable determines the location of the user-level&lt;br /&gt;
directory tree and is used by KDE applications for creating and saving&lt;br /&gt;
files. This directory tree has the highest precedence; files or settings&lt;br /&gt;
found in this directory tree will take precedence over any files or settings&lt;br /&gt;
found in other directory trees.&lt;br /&gt;
&lt;br /&gt;
This directory tree is, as the name suggests, normally located in the user's home directory. If this environment variable is not defined, the default location &amp;lt;tt&amp;gt;$HOME/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; is used.&lt;br /&gt;
&lt;br /&gt;
If the environment variable has a value that starts with a tilde (~), the tilde is replaced with the user's home directory at runtime. In order to use this, care must be taken to add proper quoting, otherwise the shell might do the expansion, resulting in undesired behavior in combination with &amp;lt;tt&amp;gt;su&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== KDEROOTHOME ===&lt;br /&gt;
In order to prevent problems with applications that run as root saving&lt;br /&gt;
files with root access permissions in the user's home directory, the &amp;lt;tt&amp;gt;KDEROOTHOME&amp;lt;/tt&amp;gt;&lt;br /&gt;
environment variable has been introduced in the KDE 3.x series. Applications&lt;br /&gt;
that run with uid 0 (root) will use this variable to determine the location of&lt;br /&gt;
the user level directory and where to save their files. If this variable is&lt;br /&gt;
not defined, the root user's home directory is looked up in the password&lt;br /&gt;
file and .kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt; is appended. Usually that results in &amp;lt;tt&amp;gt;/root/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== KDEDIRS ===&lt;br /&gt;
It is possible to specify multiple system-level directory trees. This allows groups of users to each dedicate a directory to their group. Such an additional directory tree can contain additional applications, specialized application resources or a specific set of default configurations suitable for the group. Specifying default configurations this way instead of using a /etc/skel construction has the advantage that changes in the default configuration can be made after the user's account has been created.&lt;br /&gt;
&lt;br /&gt;
The directories in $KDEDIRS should be separated with a colon (:). The directories are listed in order of precedence: the first directory has the highest precedence, the last one has the lowest precedence.&lt;br /&gt;
&lt;br /&gt;
Since a group-level directory tree should normally override any settings present at the system level, one should list the group-level directory tree before the system level directory tree.&lt;br /&gt;
&lt;br /&gt;
In general communication, references to the directory trees are made in&lt;br /&gt;
terms of $KDEHOME to indicate the applicable user-level directory tree,&lt;br /&gt;
and in terms of $KDEDIRS to indicate any of the system-level directory trees.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
A staff member at a university could have the following settings:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEROOTHOME='/root/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the user settings are saved under the .kde3 directory&lt;br /&gt;
in the user's home directory. Applications that run as root will save their&lt;br /&gt;
settings to /root/.kde3. KDE 3 has been installed to /opt/kde3 but there is&lt;br /&gt;
also an additional directory tree located at /opt/kde_staff. Configuration&lt;br /&gt;
files under that directory will take precedence over the ones in the /opt/kde3&lt;br /&gt;
system directories. /opt/kde_staff could contain additional applications that&lt;br /&gt;
should only be available to staff members.&lt;br /&gt;
&lt;br /&gt;
== Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
Each directory tree used by KDE has a fixed directory structure. However, directories&lt;br /&gt;
that are not relevant for a certain tree can be left out. For example,&lt;br /&gt;
directories used for temporary files are usually only found under $KDEHOME but&lt;br /&gt;
not in any other directory tree.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The KDE runtime environment combines the subdirectories found under the&lt;br /&gt;
various directory trees and refers to them as a single KDE resource. The&lt;br /&gt;
KDE resource name is listed in the tables below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are three broad categories: files that are&lt;br /&gt;
CPU/architecture-specific, files that are host-specific and files that are not specific with&lt;br /&gt;
regard to host, CPU or architecture.&lt;br /&gt;
&lt;br /&gt;
CPU/architecture-specific directories:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|bin/}} || exe || Used for KDE executables.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cgi-bin/}} || cgi || CGI scipts that can be used by the KDE Help Center.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || lib || Used for KDE libraries.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/kde&amp;lt;sub &amp;gt;3&amp;lt;var &amp;gt;&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || module || This directory contains components, plugins and other runtime loadable objects for use by KDE 3.x applications.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following are host-specific directories. They are only available under&lt;br /&gt;
$KDEHOME and are normally symlinked to locations outside the $KDEHOME&lt;br /&gt;
directory tree.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|socket-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Sockets|socket]] || This directory contains communication sockets. The filesystem used by $KDEHOME may not be suitable for communication sockets. For that reason this directory is symlinked to another location by default.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|tmp-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Temporary Files|tmp]] || This directory is used for temporary files. The filesystem used by $KDEHOME may be on a network, so, for performance reasons, this directory is symlinked by default to a location more likely to be on a local filesystem.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cache-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Cache Files|cache]] || New in KDE 3.2. This directory is used for cached information such as HTTP objects, formatted help pages and the system configuration cache (ksycoca).&lt;br /&gt;
&lt;br /&gt;
Since this is non-essential information, this directory is&lt;br /&gt;
symlinked to a location outside $KDEHOME by default to make it easier&lt;br /&gt;
to make backups of other information and reclaim diskspace.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The majority of directories involves data that is not CPU-, architecture- or&lt;br /&gt;
host-specific. All these directories are prefixed with {{path|share/}}:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/applnk/}} || apps || Contains .desktop files describing the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/apps/}} || data || Contains application-specific data files. Each application has a subdirectory here for storing its files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/}} || config || Contains configuration files. Configuration files are normally named after the application they belong to, followed by &amp;quot;rc&amp;quot;. There are also files that are specific to a component and as such referenced by all applications that use that component. A special case is &amp;quot;kdeglobals&amp;quot;: this file is read by all KDE applications.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/session/}} || - || This directory is used by session management and is normally only available under $KDEHOME. At the end of a session, KDE applications store their state here. The file names start with the name of the application followed by a number. The session manager &amp;quot;ksmserver&amp;quot; stores references to these numbers when saving a session in &amp;quot;ksmserverrc&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/doc/HTML/}} || html || Documentation of KDE applications is stored here. Documentation is categorized by language and the application it belongs to. &lt;br /&gt;
&lt;br /&gt;
Normally, at least two files can be found in a directory: &amp;quot;index.docbook&amp;quot;, which contains the documentation in the unformatted docbook format, and &amp;quot;index.cache.bz2&amp;quot;, which contains the same documentation formatted as bzip2 compressed HTML. The HTML version is used by khelpcenter; if the HTML version is missing, it will regenerate it from the docbook version, but this is a time-consuming process.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/icons/}} || icon || Icons are stored under this directory, categorized by theme, dimension and usage category.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mimelnk/}} || mime || Up until KDE4, .desktop files that describe MIME types were stored in this directory.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mime/}} || mime || Starting with KDE4, desktop files that describe MIME types are stored in this directory. This data is shared by other software as well and is part of a freedesktop.org specification.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/services/}}&amp;lt;br&amp;gt;{{path|share/kde4/services/}} || services || This directory contains .desktop files that describe services. Services and Applications are very similar; the major difference is that a Service is usually used by other Services or Applications, while an Application is in general started by the user. Services do not appear in the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/servicetypes/}}&amp;lt;br&amp;gt;{{path|share/kde4/servicetypes/}} || servicetypes || This directory contains .desktop files that describe service types. A service type usually represents a certain programming interface. Applications and Services include the servicetypes that they provide in their .desktop files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/sounds/}} || sound || This directory contains sound files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/templates/}} || templates || This directory contains templates for creating files of various types. A template consists of a .desktop file that describes the file and includes a reference to a file in the .source subdirectory. The templates in this directory appear in the &amp;quot;Create New&amp;quot; menu available on the desktop and in the file browser. When a user selects a template from the menu, its source file is copied.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/wallpapers/}} || wallpaper || This directory contains images that can be used as background pictures.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Outside the Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
As mentioned in the description of the directory tree, there are three host-specific directories that are usually symlinked to other locations. If the directories do not already exist, the following symlinks and directories will be created using the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility. Since both &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt; are world writable, there is a possibility that one of the mentioned directories already exists but is owned by another user. In that case, the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility will create a new directory with an alternative name and link to that instead.&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/socket-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/ksocket-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
The command &amp;lt;tt&amp;gt;lnusertemp socket&amp;lt;/tt&amp;gt; creates a directory for local communication sockets and point a symlink to it. The combined length of the directory name and the name of any communication socket should not exceed 106 characters. By default this directory is created under &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt;, but other locations can be used by setting the KDETMP environment variable.&lt;br /&gt;
&lt;br /&gt;
=== Temporary Files ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/tmp-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/kde-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
The command &amp;lt;tt&amp;gt;lnusertemp tmp&amp;lt;/tt&amp;gt; creates a directory for temporary files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
=== Cache Files ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/cache-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
 &lt;br /&gt;
Default destination: {{path|/var/tmp/kdecache-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
The command &amp;lt;tt&amp;gt;lnusertemp cache&amp;lt;/tt&amp;gt; creates a directory for cache files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
The system configuration cache (&amp;lt;tt &amp;gt;ksycoca&amp;lt;/tt &amp;gt; and &amp;lt;tt &amp;gt;ksycocastamp&amp;lt;/tt &amp;gt;) is located in here. It is recommended NOT to delete these files during boot since that will slow down the startup of KDE.&lt;br /&gt;
&lt;br /&gt;
By default this directory is created under &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt;, other locations&lt;br /&gt;
can be used by setting the KDEVARTMP environment variable.&lt;br /&gt;
&lt;br /&gt;
== Adding Lookup Locations ==&lt;br /&gt;
&lt;br /&gt;
KDE applications look up data files using the resource names listed in the&lt;br /&gt;
[#dir_structure Directory Tree] section.  The KDE runtime&lt;br /&gt;
environment translates these names to actual directories&lt;br /&gt;
by combining the locations of the directory trees with the directories&lt;br /&gt;
listed in the tables.&lt;br /&gt;
&lt;br /&gt;
==== Defining Search Paths ====&lt;br /&gt;
&lt;br /&gt;
A user has the following directory tree settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an application now looks for a &amp;quot;wallpaper&amp;quot; file, the directory &amp;quot;share/wallpapers/&amp;quot; is added to each of the&lt;br /&gt;
directory trees. All of the&lt;br /&gt;
resulting directories are then searched for the file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By adding more directory tree to the KDEDIRS environment variable&lt;br /&gt;
it is possible to expand the number of directories that are being searched.&lt;br /&gt;
Sometimes it is desirable to include only a single directory in a search&lt;br /&gt;
but not a whole directory tree. Additional directories can be configured&lt;br /&gt;
in the kdeglobals configuration file in the &amp;quot;Directories&amp;quot; section.&lt;br /&gt;
To do so assign one or more directories to the key &amp;quot;dir_&amp;quot; followed by the&lt;br /&gt;
name of the resource. Multiple directories are separated by commas (,).&lt;br /&gt;
&lt;br /&gt;
==== Adding a Resource Directory ====&lt;br /&gt;
&lt;br /&gt;
To add the directory /data/photos to the wallpaper resource, put the&lt;br /&gt;
following two lines in kdeglobals:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Directories]&lt;br /&gt;
dir_wallpaper=/data/photos&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the application now looks for wallpaper files, it will look in the&lt;br /&gt;
following locations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
/data/photos&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy</id>
		<title>KDE System Administration/KDE Filesystem Hierarchy</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy"/>
				<updated>2010-09-14T12:58:52Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Temporary Files */ will not run with nbsp&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|KDE_System_Administration/KDE_Filesystem_Hierarchy}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
KDE defines a filesystem hierarchy that is used by the KDE environment&lt;br /&gt;
itself as well as all KDE applications. In general, KDE stores all its&lt;br /&gt;
files in a fixed directory tree.&lt;br /&gt;
&lt;br /&gt;
By default, there are two such directory trees: one at the system&lt;br /&gt;
level and one at the user level in the user's home directory. However,&lt;br /&gt;
as a system administrator you can create additional trees.&lt;br /&gt;
&lt;br /&gt;
KDE and KDE applications look up files by scanning the directory trees&lt;br /&gt;
in order of precedence. When a file is&lt;br /&gt;
present in multiple directory trees, the file from the first-listed&lt;br /&gt;
tree takes precedence.&lt;br /&gt;
Normally, the tree located in the user's home directory has the highest&lt;br /&gt;
precedence. This is also the directory tree that changes are&lt;br /&gt;
written to.&lt;br /&gt;
&lt;br /&gt;
For configuration files, the story is slightly&lt;br /&gt;
different. If multiple configuration files with the same name are found in the directory&lt;br /&gt;
trees, their content is combined. The precedence order&lt;br /&gt;
of the directory trees plays a role here: when two files define the same&lt;br /&gt;
configuration key, the file with the highest precedence determines which&lt;br /&gt;
value is used for the key.&lt;br /&gt;
&lt;br /&gt;
== Location of the Directory Trees ==&lt;br /&gt;
&lt;br /&gt;
The location of the KDE Directory Trees is determined by a number of&lt;br /&gt;
environment variables, each of which is covered below.&lt;br /&gt;
&lt;br /&gt;
=== KDEHOME ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;KDEHOME&amp;lt;/tt&amp;gt; environment variable determines the location of the user-level&lt;br /&gt;
directory tree and is used by KDE applications for creating and saving&lt;br /&gt;
files. This directory tree has the highest precedence; files or settings&lt;br /&gt;
found in this directory tree will take precedence over any files or settings&lt;br /&gt;
found in other directory trees.&lt;br /&gt;
&lt;br /&gt;
This directory tree is, as the name suggests, normally located in the user's home directory. If this environment variable is not defined, the default location &amp;lt;tt&amp;gt;$HOME/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; is used.&lt;br /&gt;
&lt;br /&gt;
If the environment variable has a value that starts with a tilde (~), the tilde is replaced with the user's home directory at runtime. In order to use this, care must be taken to add proper quoting, otherwise the shell might do the expansion, resulting in undesired behavior in combination with &amp;lt;tt&amp;gt;su&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== KDEROOTHOME ===&lt;br /&gt;
In order to prevent problems with applications that run as root saving&lt;br /&gt;
files with root access permissions in the user's home directory, the &amp;lt;tt&amp;gt;KDEROOTHOME&amp;lt;/tt&amp;gt;&lt;br /&gt;
environment variable has been introduced in the KDE 3.x series. Applications&lt;br /&gt;
that run with uid 0 (root) will use this variable to determine the location of&lt;br /&gt;
the user level directory and where to save their files. If this variable is&lt;br /&gt;
not defined, the root user's home directory is looked up in the password&lt;br /&gt;
file and .kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt; is appended. Usually that results in &amp;lt;tt&amp;gt;/root/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== KDEDIRS ===&lt;br /&gt;
It is possible to specify multiple system-level directory trees. This allows groups of users to each dedicate a directory to their group. Such an additional directory tree can contain additional applications, specialized application resources or a specific set of default configurations suitable for the group. Specifying default configurations this way instead of using a /etc/skel construction has the advantage that changes in the default configuration can be made after the user's account has been created.&lt;br /&gt;
&lt;br /&gt;
The directories in $KDEDIRS should be separated with a colon (:). The directories are listed in order of precedence: the first directory has the highest precedence, the last one has the lowest precedence.&lt;br /&gt;
&lt;br /&gt;
Since a group-level directory tree should normally override any settings present at the system level, one should list the group-level directory tree before the system level directory tree.&lt;br /&gt;
&lt;br /&gt;
In general communication, references to the directory trees are made in&lt;br /&gt;
terms of $KDEHOME to indicate the applicable user-level directory tree,&lt;br /&gt;
and in terms of $KDEDIRS to indicate any of the system-level directory trees.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
A staff member at a university could have the following settings:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEROOTHOME='/root/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the user settings are saved under the .kde3 directory&lt;br /&gt;
in the user's home directory. Applications that run as root will save their&lt;br /&gt;
settings to /root/.kde3. KDE 3 has been installed to /opt/kde3 but there is&lt;br /&gt;
also an additional directory tree located at /opt/kde_staff. Configuration&lt;br /&gt;
files under that directory will take precedence over the ones in the /opt/kde3&lt;br /&gt;
system directories. /opt/kde_staff could contain additional applications that&lt;br /&gt;
should only be available to staff members.&lt;br /&gt;
&lt;br /&gt;
== Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
Each directory tree used by KDE has a fixed directory structure. However, directories&lt;br /&gt;
that are not relevant for a certain tree can be left out. For example,&lt;br /&gt;
directories used for temporary files are usually only found under $KDEHOME but&lt;br /&gt;
not in any other directory tree.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The KDE runtime environment combines the subdirectories found under the&lt;br /&gt;
various directory trees and refers to them as a single KDE resource. The&lt;br /&gt;
KDE resource name is listed in the tables below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are three broad categories: files that are&lt;br /&gt;
CPU/architecture-specific, files that are host-specific and files that are not specific with&lt;br /&gt;
regard to host, CPU or architecture.&lt;br /&gt;
&lt;br /&gt;
CPU/architecture-specific directories:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|bin/}} || exe || Used for KDE executables.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cgi-bin/}} || cgi || CGI scipts that can be used by the KDE Help Center.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || lib || Used for KDE libraries.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/kde&amp;lt;sub &amp;gt;3&amp;lt;var &amp;gt;&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || module || This directory contains components, plugins and other runtime loadable objects for use by KDE 3.x applications.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following are host-specific directories. They are only available under&lt;br /&gt;
$KDEHOME and are normally symlinked to locations outside the $KDEHOME&lt;br /&gt;
directory tree.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|socket-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Sockets|socket]] || This directory contains communication sockets. The filesystem used by $KDEHOME may not be suitable for communication sockets. For that reason this directory is symlinked to another location by default.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|tmp-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Temporary Files|tmp]] || This directory is used for temporary files. The filesystem used by $KDEHOME may be on a network, so, for performance reasons, this directory is symlinked by default to a location more likely to be on a local filesystem.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cache-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Cache Files|cache]] || New in KDE 3.2. This directory is used for cached information such as HTTP objects, formatted help pages and the system configuration cache (ksycoca).&lt;br /&gt;
&lt;br /&gt;
Since this is non-essential information, this directory is&lt;br /&gt;
symlinked to a location outside $KDEHOME by default to make it easier&lt;br /&gt;
to make backups of other information and reclaim diskspace.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The majority of directories involves data that is not CPU-, architecture- or&lt;br /&gt;
host-specific. All these directories are prefixed with {{path|share/}}:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/applnk/}} || apps || Contains .desktop files describing the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/apps/}} || data || Contains application-specific data files. Each application has a subdirectory here for storing its files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/}} || config || Contains configuration files. Configuration files are normally named after the application they belong to, followed by &amp;quot;rc&amp;quot;. There are also files that are specific to a component and as such referenced by all applications that use that component. A special case is &amp;quot;kdeglobals&amp;quot;: this file is read by all KDE applications.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/session/}} || - || This directory is used by session management and is normally only available under $KDEHOME. At the end of a session, KDE applications store their state here. The file names start with the name of the application followed by a number. The session manager &amp;quot;ksmserver&amp;quot; stores references to these numbers when saving a session in &amp;quot;ksmserverrc&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/doc/HTML/}} || html || Documentation of KDE applications is stored here. Documentation is categorized by language and the application it belongs to. &lt;br /&gt;
&lt;br /&gt;
Normally, at least two files can be found in a directory: &amp;quot;index.docbook&amp;quot;, which contains the documentation in the unformatted docbook format, and &amp;quot;index.cache.bz2&amp;quot;, which contains the same documentation formatted as bzip2 compressed HTML. The HTML version is used by khelpcenter; if the HTML version is missing, it will regenerate it from the docbook version, but this is a time-consuming process.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/icons/}} || icon || Icons are stored under this directory, categorized by theme, dimension and usage category.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mimelnk/}} || mime || Up until KDE4, .desktop files that describe MIME types were stored in this directory.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mime/}} || mime || Starting with KDE4, desktop files that describe MIME types are stored in this directory. This data is shared by other software as well and is part of a freedesktop.org specification.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/services/}}&amp;lt;br&amp;gt;{{path|share/kde4/services/}} || services || This directory contains .desktop files that describe services. Services and Applications are very similar; the major difference is that a Service is usually used by other Services or Applications, while an Application is in general started by the user. Services do not appear in the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/servicetypes/}}&amp;lt;br&amp;gt;{{path|share/kde4/servicetypes/}} || servicetypes || This directory contains .desktop files that describe service types. A service type usually represents a certain programming interface. Applications and Services include the servicetypes that they provide in their .desktop files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/sounds/}} || sound || This directory contains sound files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/templates/}} || templates || This directory contains templates for creating files of various types. A template consists of a .desktop file that describes the file and includes a reference to a file in the .source subdirectory. The templates in this directory appear in the &amp;quot;Create New&amp;quot; menu available on the desktop and in the file browser. When a user selects a template from the menu, its source file is copied.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/wallpapers/}} || wallpaper || This directory contains images that can be used as background pictures.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Outside the Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
As mentioned in the description of the directory tree, there are three host-specific directories that are usually symlinked to other locations. If the directories do not already exist, the following symlinks and directories will be created using the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility. Since both &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt; are world writable, there is a possibility that one of the mentioned directories already exists but is owned by another user. In that case, the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility will create a new directory with an alternative name and link to that instead.&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/socket-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/ksocket-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;socket&amp;lt;/tt&amp;gt; creates a directory for local communication sockets and point a symlink to it. The combined length of the directory name and the name of any communication socket should not exceed 106 characters. By default this directory is created under &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt;, but other locations can be used by setting the KDETMP environment variable.&lt;br /&gt;
&lt;br /&gt;
=== Temporary Files ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/tmp-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/kde-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
The command &amp;lt;tt&amp;gt;lnusertemp tmp&amp;lt;/tt&amp;gt; creates a directory for temporary files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
=== Cache Files ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/cache-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
 &lt;br /&gt;
Default destination: {{path|/var/tmp/kdecache-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
The command &amp;lt;tt&amp;gt;lnusertemp cache&amp;lt;/tt&amp;gt; creates a directory for cache files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
The system configuration cache (&amp;lt;tt &amp;gt;ksycoca&amp;lt;/tt &amp;gt; and &amp;lt;tt &amp;gt;ksycocastamp&amp;lt;/tt &amp;gt;) is located in here. It is recommended NOT to delete these files during boot since that will slow down the startup of KDE.&lt;br /&gt;
&lt;br /&gt;
By default this directory is created under &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt;, other locations&lt;br /&gt;
can be used by setting the KDEVARTMP environment variable.&lt;br /&gt;
&lt;br /&gt;
== Adding Lookup Locations ==&lt;br /&gt;
&lt;br /&gt;
KDE applications look up data files using the resource names listed in the&lt;br /&gt;
[#dir_structure Directory Tree] section.  The KDE runtime&lt;br /&gt;
environment translates these names to actual directories&lt;br /&gt;
by combining the locations of the directory trees with the directories&lt;br /&gt;
listed in the tables.&lt;br /&gt;
&lt;br /&gt;
==== Defining Search Paths ====&lt;br /&gt;
&lt;br /&gt;
A user has the following directory tree settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an application now looks for a &amp;quot;wallpaper&amp;quot; file, the directory &amp;quot;share/wallpapers/&amp;quot; is added to each of the&lt;br /&gt;
directory trees. All of the&lt;br /&gt;
resulting directories are then searched for the file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By adding more directory tree to the KDEDIRS environment variable&lt;br /&gt;
it is possible to expand the number of directories that are being searched.&lt;br /&gt;
Sometimes it is desirable to include only a single directory in a search&lt;br /&gt;
but not a whole directory tree. Additional directories can be configured&lt;br /&gt;
in the kdeglobals configuration file in the &amp;quot;Directories&amp;quot; section.&lt;br /&gt;
To do so assign one or more directories to the key &amp;quot;dir_&amp;quot; followed by the&lt;br /&gt;
name of the resource. Multiple directories are separated by commas (,).&lt;br /&gt;
&lt;br /&gt;
==== Adding a Resource Directory ====&lt;br /&gt;
&lt;br /&gt;
To add the directory /data/photos to the wallpaper resource, put the&lt;br /&gt;
following two lines in kdeglobals:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Directories]&lt;br /&gt;
dir_wallpaper=/data/photos&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the application now looks for wallpaper files, it will look in the&lt;br /&gt;
following locations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
/data/photos&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy</id>
		<title>KDE System Administration/KDE Filesystem Hierarchy</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy"/>
				<updated>2010-09-14T12:57:52Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Cache Files */ Parameter style&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|KDE_System_Administration/KDE_Filesystem_Hierarchy}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
KDE defines a filesystem hierarchy that is used by the KDE environment&lt;br /&gt;
itself as well as all KDE applications. In general, KDE stores all its&lt;br /&gt;
files in a fixed directory tree.&lt;br /&gt;
&lt;br /&gt;
By default, there are two such directory trees: one at the system&lt;br /&gt;
level and one at the user level in the user's home directory. However,&lt;br /&gt;
as a system administrator you can create additional trees.&lt;br /&gt;
&lt;br /&gt;
KDE and KDE applications look up files by scanning the directory trees&lt;br /&gt;
in order of precedence. When a file is&lt;br /&gt;
present in multiple directory trees, the file from the first-listed&lt;br /&gt;
tree takes precedence.&lt;br /&gt;
Normally, the tree located in the user's home directory has the highest&lt;br /&gt;
precedence. This is also the directory tree that changes are&lt;br /&gt;
written to.&lt;br /&gt;
&lt;br /&gt;
For configuration files, the story is slightly&lt;br /&gt;
different. If multiple configuration files with the same name are found in the directory&lt;br /&gt;
trees, their content is combined. The precedence order&lt;br /&gt;
of the directory trees plays a role here: when two files define the same&lt;br /&gt;
configuration key, the file with the highest precedence determines which&lt;br /&gt;
value is used for the key.&lt;br /&gt;
&lt;br /&gt;
== Location of the Directory Trees ==&lt;br /&gt;
&lt;br /&gt;
The location of the KDE Directory Trees is determined by a number of&lt;br /&gt;
environment variables, each of which is covered below.&lt;br /&gt;
&lt;br /&gt;
=== KDEHOME ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;KDEHOME&amp;lt;/tt&amp;gt; environment variable determines the location of the user-level&lt;br /&gt;
directory tree and is used by KDE applications for creating and saving&lt;br /&gt;
files. This directory tree has the highest precedence; files or settings&lt;br /&gt;
found in this directory tree will take precedence over any files or settings&lt;br /&gt;
found in other directory trees.&lt;br /&gt;
&lt;br /&gt;
This directory tree is, as the name suggests, normally located in the user's home directory. If this environment variable is not defined, the default location &amp;lt;tt&amp;gt;$HOME/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; is used.&lt;br /&gt;
&lt;br /&gt;
If the environment variable has a value that starts with a tilde (~), the tilde is replaced with the user's home directory at runtime. In order to use this, care must be taken to add proper quoting, otherwise the shell might do the expansion, resulting in undesired behavior in combination with &amp;lt;tt&amp;gt;su&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== KDEROOTHOME ===&lt;br /&gt;
In order to prevent problems with applications that run as root saving&lt;br /&gt;
files with root access permissions in the user's home directory, the &amp;lt;tt&amp;gt;KDEROOTHOME&amp;lt;/tt&amp;gt;&lt;br /&gt;
environment variable has been introduced in the KDE 3.x series. Applications&lt;br /&gt;
that run with uid 0 (root) will use this variable to determine the location of&lt;br /&gt;
the user level directory and where to save their files. If this variable is&lt;br /&gt;
not defined, the root user's home directory is looked up in the password&lt;br /&gt;
file and .kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt; is appended. Usually that results in &amp;lt;tt&amp;gt;/root/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== KDEDIRS ===&lt;br /&gt;
It is possible to specify multiple system-level directory trees. This allows groups of users to each dedicate a directory to their group. Such an additional directory tree can contain additional applications, specialized application resources or a specific set of default configurations suitable for the group. Specifying default configurations this way instead of using a /etc/skel construction has the advantage that changes in the default configuration can be made after the user's account has been created.&lt;br /&gt;
&lt;br /&gt;
The directories in $KDEDIRS should be separated with a colon (:). The directories are listed in order of precedence: the first directory has the highest precedence, the last one has the lowest precedence.&lt;br /&gt;
&lt;br /&gt;
Since a group-level directory tree should normally override any settings present at the system level, one should list the group-level directory tree before the system level directory tree.&lt;br /&gt;
&lt;br /&gt;
In general communication, references to the directory trees are made in&lt;br /&gt;
terms of $KDEHOME to indicate the applicable user-level directory tree,&lt;br /&gt;
and in terms of $KDEDIRS to indicate any of the system-level directory trees.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
A staff member at a university could have the following settings:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEROOTHOME='/root/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the user settings are saved under the .kde3 directory&lt;br /&gt;
in the user's home directory. Applications that run as root will save their&lt;br /&gt;
settings to /root/.kde3. KDE 3 has been installed to /opt/kde3 but there is&lt;br /&gt;
also an additional directory tree located at /opt/kde_staff. Configuration&lt;br /&gt;
files under that directory will take precedence over the ones in the /opt/kde3&lt;br /&gt;
system directories. /opt/kde_staff could contain additional applications that&lt;br /&gt;
should only be available to staff members.&lt;br /&gt;
&lt;br /&gt;
== Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
Each directory tree used by KDE has a fixed directory structure. However, directories&lt;br /&gt;
that are not relevant for a certain tree can be left out. For example,&lt;br /&gt;
directories used for temporary files are usually only found under $KDEHOME but&lt;br /&gt;
not in any other directory tree.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The KDE runtime environment combines the subdirectories found under the&lt;br /&gt;
various directory trees and refers to them as a single KDE resource. The&lt;br /&gt;
KDE resource name is listed in the tables below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are three broad categories: files that are&lt;br /&gt;
CPU/architecture-specific, files that are host-specific and files that are not specific with&lt;br /&gt;
regard to host, CPU or architecture.&lt;br /&gt;
&lt;br /&gt;
CPU/architecture-specific directories:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|bin/}} || exe || Used for KDE executables.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cgi-bin/}} || cgi || CGI scipts that can be used by the KDE Help Center.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || lib || Used for KDE libraries.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/kde&amp;lt;sub &amp;gt;3&amp;lt;var &amp;gt;&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || module || This directory contains components, plugins and other runtime loadable objects for use by KDE 3.x applications.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following are host-specific directories. They are only available under&lt;br /&gt;
$KDEHOME and are normally symlinked to locations outside the $KDEHOME&lt;br /&gt;
directory tree.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|socket-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Sockets|socket]] || This directory contains communication sockets. The filesystem used by $KDEHOME may not be suitable for communication sockets. For that reason this directory is symlinked to another location by default.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|tmp-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Temporary Files|tmp]] || This directory is used for temporary files. The filesystem used by $KDEHOME may be on a network, so, for performance reasons, this directory is symlinked by default to a location more likely to be on a local filesystem.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cache-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Cache Files|cache]] || New in KDE 3.2. This directory is used for cached information such as HTTP objects, formatted help pages and the system configuration cache (ksycoca).&lt;br /&gt;
&lt;br /&gt;
Since this is non-essential information, this directory is&lt;br /&gt;
symlinked to a location outside $KDEHOME by default to make it easier&lt;br /&gt;
to make backups of other information and reclaim diskspace.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The majority of directories involves data that is not CPU-, architecture- or&lt;br /&gt;
host-specific. All these directories are prefixed with {{path|share/}}:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/applnk/}} || apps || Contains .desktop files describing the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/apps/}} || data || Contains application-specific data files. Each application has a subdirectory here for storing its files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/}} || config || Contains configuration files. Configuration files are normally named after the application they belong to, followed by &amp;quot;rc&amp;quot;. There are also files that are specific to a component and as such referenced by all applications that use that component. A special case is &amp;quot;kdeglobals&amp;quot;: this file is read by all KDE applications.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/session/}} || - || This directory is used by session management and is normally only available under $KDEHOME. At the end of a session, KDE applications store their state here. The file names start with the name of the application followed by a number. The session manager &amp;quot;ksmserver&amp;quot; stores references to these numbers when saving a session in &amp;quot;ksmserverrc&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/doc/HTML/}} || html || Documentation of KDE applications is stored here. Documentation is categorized by language and the application it belongs to. &lt;br /&gt;
&lt;br /&gt;
Normally, at least two files can be found in a directory: &amp;quot;index.docbook&amp;quot;, which contains the documentation in the unformatted docbook format, and &amp;quot;index.cache.bz2&amp;quot;, which contains the same documentation formatted as bzip2 compressed HTML. The HTML version is used by khelpcenter; if the HTML version is missing, it will regenerate it from the docbook version, but this is a time-consuming process.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/icons/}} || icon || Icons are stored under this directory, categorized by theme, dimension and usage category.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mimelnk/}} || mime || Up until KDE4, .desktop files that describe MIME types were stored in this directory.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mime/}} || mime || Starting with KDE4, desktop files that describe MIME types are stored in this directory. This data is shared by other software as well and is part of a freedesktop.org specification.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/services/}}&amp;lt;br&amp;gt;{{path|share/kde4/services/}} || services || This directory contains .desktop files that describe services. Services and Applications are very similar; the major difference is that a Service is usually used by other Services or Applications, while an Application is in general started by the user. Services do not appear in the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/servicetypes/}}&amp;lt;br&amp;gt;{{path|share/kde4/servicetypes/}} || servicetypes || This directory contains .desktop files that describe service types. A service type usually represents a certain programming interface. Applications and Services include the servicetypes that they provide in their .desktop files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/sounds/}} || sound || This directory contains sound files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/templates/}} || templates || This directory contains templates for creating files of various types. A template consists of a .desktop file that describes the file and includes a reference to a file in the .source subdirectory. The templates in this directory appear in the &amp;quot;Create New&amp;quot; menu available on the desktop and in the file browser. When a user selects a template from the menu, its source file is copied.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/wallpapers/}} || wallpaper || This directory contains images that can be used as background pictures.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Outside the Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
As mentioned in the description of the directory tree, there are three host-specific directories that are usually symlinked to other locations. If the directories do not already exist, the following symlinks and directories will be created using the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility. Since both &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt; are world writable, there is a possibility that one of the mentioned directories already exists but is owned by another user. In that case, the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility will create a new directory with an alternative name and link to that instead.&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/socket-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/ksocket-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;socket&amp;lt;/tt&amp;gt; creates a directory for local communication sockets and point a symlink to it. The combined length of the directory name and the name of any communication socket should not exceed 106 characters. By default this directory is created under &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt;, but other locations can be used by setting the KDETMP environment variable.&lt;br /&gt;
&lt;br /&gt;
=== Temporary Files ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/tmp-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/kde-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;tmp&amp;lt;/tt&amp;gt; creates a directory for temporary files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
=== Cache Files ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/cache-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
 &lt;br /&gt;
Default destination: {{path|/var/tmp/kdecache-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
The command &amp;lt;tt&amp;gt;lnusertemp cache&amp;lt;/tt&amp;gt; creates a directory for cache files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
The system configuration cache (&amp;lt;tt &amp;gt;ksycoca&amp;lt;/tt &amp;gt; and &amp;lt;tt &amp;gt;ksycocastamp&amp;lt;/tt &amp;gt;) is located in here. It is recommended NOT to delete these files during boot since that will slow down the startup of KDE.&lt;br /&gt;
&lt;br /&gt;
By default this directory is created under &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt;, other locations&lt;br /&gt;
can be used by setting the KDEVARTMP environment variable.&lt;br /&gt;
&lt;br /&gt;
== Adding Lookup Locations ==&lt;br /&gt;
&lt;br /&gt;
KDE applications look up data files using the resource names listed in the&lt;br /&gt;
[#dir_structure Directory Tree] section.  The KDE runtime&lt;br /&gt;
environment translates these names to actual directories&lt;br /&gt;
by combining the locations of the directory trees with the directories&lt;br /&gt;
listed in the tables.&lt;br /&gt;
&lt;br /&gt;
==== Defining Search Paths ====&lt;br /&gt;
&lt;br /&gt;
A user has the following directory tree settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an application now looks for a &amp;quot;wallpaper&amp;quot; file, the directory &amp;quot;share/wallpapers/&amp;quot; is added to each of the&lt;br /&gt;
directory trees. All of the&lt;br /&gt;
resulting directories are then searched for the file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By adding more directory tree to the KDEDIRS environment variable&lt;br /&gt;
it is possible to expand the number of directories that are being searched.&lt;br /&gt;
Sometimes it is desirable to include only a single directory in a search&lt;br /&gt;
but not a whole directory tree. Additional directories can be configured&lt;br /&gt;
in the kdeglobals configuration file in the &amp;quot;Directories&amp;quot; section.&lt;br /&gt;
To do so assign one or more directories to the key &amp;quot;dir_&amp;quot; followed by the&lt;br /&gt;
name of the resource. Multiple directories are separated by commas (,).&lt;br /&gt;
&lt;br /&gt;
==== Adding a Resource Directory ====&lt;br /&gt;
&lt;br /&gt;
To add the directory /data/photos to the wallpaper resource, put the&lt;br /&gt;
following two lines in kdeglobals:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Directories]&lt;br /&gt;
dir_wallpaper=/data/photos&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the application now looks for wallpaper files, it will look in the&lt;br /&gt;
following locations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
/data/photos&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy</id>
		<title>KDE System Administration/KDE Filesystem Hierarchy</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy"/>
				<updated>2010-09-14T12:55:41Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Temporary Files */ parameter style&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|KDE_System_Administration/KDE_Filesystem_Hierarchy}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
KDE defines a filesystem hierarchy that is used by the KDE environment&lt;br /&gt;
itself as well as all KDE applications. In general, KDE stores all its&lt;br /&gt;
files in a fixed directory tree.&lt;br /&gt;
&lt;br /&gt;
By default, there are two such directory trees: one at the system&lt;br /&gt;
level and one at the user level in the user's home directory. However,&lt;br /&gt;
as a system administrator you can create additional trees.&lt;br /&gt;
&lt;br /&gt;
KDE and KDE applications look up files by scanning the directory trees&lt;br /&gt;
in order of precedence. When a file is&lt;br /&gt;
present in multiple directory trees, the file from the first-listed&lt;br /&gt;
tree takes precedence.&lt;br /&gt;
Normally, the tree located in the user's home directory has the highest&lt;br /&gt;
precedence. This is also the directory tree that changes are&lt;br /&gt;
written to.&lt;br /&gt;
&lt;br /&gt;
For configuration files, the story is slightly&lt;br /&gt;
different. If multiple configuration files with the same name are found in the directory&lt;br /&gt;
trees, their content is combined. The precedence order&lt;br /&gt;
of the directory trees plays a role here: when two files define the same&lt;br /&gt;
configuration key, the file with the highest precedence determines which&lt;br /&gt;
value is used for the key.&lt;br /&gt;
&lt;br /&gt;
== Location of the Directory Trees ==&lt;br /&gt;
&lt;br /&gt;
The location of the KDE Directory Trees is determined by a number of&lt;br /&gt;
environment variables, each of which is covered below.&lt;br /&gt;
&lt;br /&gt;
=== KDEHOME ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;KDEHOME&amp;lt;/tt&amp;gt; environment variable determines the location of the user-level&lt;br /&gt;
directory tree and is used by KDE applications for creating and saving&lt;br /&gt;
files. This directory tree has the highest precedence; files or settings&lt;br /&gt;
found in this directory tree will take precedence over any files or settings&lt;br /&gt;
found in other directory trees.&lt;br /&gt;
&lt;br /&gt;
This directory tree is, as the name suggests, normally located in the user's home directory. If this environment variable is not defined, the default location &amp;lt;tt&amp;gt;$HOME/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; is used.&lt;br /&gt;
&lt;br /&gt;
If the environment variable has a value that starts with a tilde (~), the tilde is replaced with the user's home directory at runtime. In order to use this, care must be taken to add proper quoting, otherwise the shell might do the expansion, resulting in undesired behavior in combination with &amp;lt;tt&amp;gt;su&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== KDEROOTHOME ===&lt;br /&gt;
In order to prevent problems with applications that run as root saving&lt;br /&gt;
files with root access permissions in the user's home directory, the &amp;lt;tt&amp;gt;KDEROOTHOME&amp;lt;/tt&amp;gt;&lt;br /&gt;
environment variable has been introduced in the KDE 3.x series. Applications&lt;br /&gt;
that run with uid 0 (root) will use this variable to determine the location of&lt;br /&gt;
the user level directory and where to save their files. If this variable is&lt;br /&gt;
not defined, the root user's home directory is looked up in the password&lt;br /&gt;
file and .kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt; is appended. Usually that results in &amp;lt;tt&amp;gt;/root/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== KDEDIRS ===&lt;br /&gt;
It is possible to specify multiple system-level directory trees. This allows groups of users to each dedicate a directory to their group. Such an additional directory tree can contain additional applications, specialized application resources or a specific set of default configurations suitable for the group. Specifying default configurations this way instead of using a /etc/skel construction has the advantage that changes in the default configuration can be made after the user's account has been created.&lt;br /&gt;
&lt;br /&gt;
The directories in $KDEDIRS should be separated with a colon (:). The directories are listed in order of precedence: the first directory has the highest precedence, the last one has the lowest precedence.&lt;br /&gt;
&lt;br /&gt;
Since a group-level directory tree should normally override any settings present at the system level, one should list the group-level directory tree before the system level directory tree.&lt;br /&gt;
&lt;br /&gt;
In general communication, references to the directory trees are made in&lt;br /&gt;
terms of $KDEHOME to indicate the applicable user-level directory tree,&lt;br /&gt;
and in terms of $KDEDIRS to indicate any of the system-level directory trees.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
A staff member at a university could have the following settings:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEROOTHOME='/root/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the user settings are saved under the .kde3 directory&lt;br /&gt;
in the user's home directory. Applications that run as root will save their&lt;br /&gt;
settings to /root/.kde3. KDE 3 has been installed to /opt/kde3 but there is&lt;br /&gt;
also an additional directory tree located at /opt/kde_staff. Configuration&lt;br /&gt;
files under that directory will take precedence over the ones in the /opt/kde3&lt;br /&gt;
system directories. /opt/kde_staff could contain additional applications that&lt;br /&gt;
should only be available to staff members.&lt;br /&gt;
&lt;br /&gt;
== Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
Each directory tree used by KDE has a fixed directory structure. However, directories&lt;br /&gt;
that are not relevant for a certain tree can be left out. For example,&lt;br /&gt;
directories used for temporary files are usually only found under $KDEHOME but&lt;br /&gt;
not in any other directory tree.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The KDE runtime environment combines the subdirectories found under the&lt;br /&gt;
various directory trees and refers to them as a single KDE resource. The&lt;br /&gt;
KDE resource name is listed in the tables below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are three broad categories: files that are&lt;br /&gt;
CPU/architecture-specific, files that are host-specific and files that are not specific with&lt;br /&gt;
regard to host, CPU or architecture.&lt;br /&gt;
&lt;br /&gt;
CPU/architecture-specific directories:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|bin/}} || exe || Used for KDE executables.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cgi-bin/}} || cgi || CGI scipts that can be used by the KDE Help Center.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || lib || Used for KDE libraries.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/kde&amp;lt;sub &amp;gt;3&amp;lt;var &amp;gt;&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || module || This directory contains components, plugins and other runtime loadable objects for use by KDE 3.x applications.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following are host-specific directories. They are only available under&lt;br /&gt;
$KDEHOME and are normally symlinked to locations outside the $KDEHOME&lt;br /&gt;
directory tree.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|socket-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Sockets|socket]] || This directory contains communication sockets. The filesystem used by $KDEHOME may not be suitable for communication sockets. For that reason this directory is symlinked to another location by default.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|tmp-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Temporary Files|tmp]] || This directory is used for temporary files. The filesystem used by $KDEHOME may be on a network, so, for performance reasons, this directory is symlinked by default to a location more likely to be on a local filesystem.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cache-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Cache Files|cache]] || New in KDE 3.2. This directory is used for cached information such as HTTP objects, formatted help pages and the system configuration cache (ksycoca).&lt;br /&gt;
&lt;br /&gt;
Since this is non-essential information, this directory is&lt;br /&gt;
symlinked to a location outside $KDEHOME by default to make it easier&lt;br /&gt;
to make backups of other information and reclaim diskspace.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The majority of directories involves data that is not CPU-, architecture- or&lt;br /&gt;
host-specific. All these directories are prefixed with {{path|share/}}:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/applnk/}} || apps || Contains .desktop files describing the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/apps/}} || data || Contains application-specific data files. Each application has a subdirectory here for storing its files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/}} || config || Contains configuration files. Configuration files are normally named after the application they belong to, followed by &amp;quot;rc&amp;quot;. There are also files that are specific to a component and as such referenced by all applications that use that component. A special case is &amp;quot;kdeglobals&amp;quot;: this file is read by all KDE applications.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/session/}} || - || This directory is used by session management and is normally only available under $KDEHOME. At the end of a session, KDE applications store their state here. The file names start with the name of the application followed by a number. The session manager &amp;quot;ksmserver&amp;quot; stores references to these numbers when saving a session in &amp;quot;ksmserverrc&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/doc/HTML/}} || html || Documentation of KDE applications is stored here. Documentation is categorized by language and the application it belongs to. &lt;br /&gt;
&lt;br /&gt;
Normally, at least two files can be found in a directory: &amp;quot;index.docbook&amp;quot;, which contains the documentation in the unformatted docbook format, and &amp;quot;index.cache.bz2&amp;quot;, which contains the same documentation formatted as bzip2 compressed HTML. The HTML version is used by khelpcenter; if the HTML version is missing, it will regenerate it from the docbook version, but this is a time-consuming process.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/icons/}} || icon || Icons are stored under this directory, categorized by theme, dimension and usage category.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mimelnk/}} || mime || Up until KDE4, .desktop files that describe MIME types were stored in this directory.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mime/}} || mime || Starting with KDE4, desktop files that describe MIME types are stored in this directory. This data is shared by other software as well and is part of a freedesktop.org specification.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/services/}}&amp;lt;br&amp;gt;{{path|share/kde4/services/}} || services || This directory contains .desktop files that describe services. Services and Applications are very similar; the major difference is that a Service is usually used by other Services or Applications, while an Application is in general started by the user. Services do not appear in the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/servicetypes/}}&amp;lt;br&amp;gt;{{path|share/kde4/servicetypes/}} || servicetypes || This directory contains .desktop files that describe service types. A service type usually represents a certain programming interface. Applications and Services include the servicetypes that they provide in their .desktop files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/sounds/}} || sound || This directory contains sound files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/templates/}} || templates || This directory contains templates for creating files of various types. A template consists of a .desktop file that describes the file and includes a reference to a file in the .source subdirectory. The templates in this directory appear in the &amp;quot;Create New&amp;quot; menu available on the desktop and in the file browser. When a user selects a template from the menu, its source file is copied.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/wallpapers/}} || wallpaper || This directory contains images that can be used as background pictures.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Outside the Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
As mentioned in the description of the directory tree, there are three host-specific directories that are usually symlinked to other locations. If the directories do not already exist, the following symlinks and directories will be created using the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility. Since both &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt; are world writable, there is a possibility that one of the mentioned directories already exists but is owned by another user. In that case, the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility will create a new directory with an alternative name and link to that instead.&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/socket-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/ksocket-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;socket&amp;lt;/tt&amp;gt; creates a directory for local communication sockets and point a symlink to it. The combined length of the directory name and the name of any communication socket should not exceed 106 characters. By default this directory is created under &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt;, but other locations can be used by setting the KDETMP environment variable.&lt;br /&gt;
&lt;br /&gt;
=== Temporary Files ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/tmp-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/kde-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;tmp&amp;lt;/tt&amp;gt; creates a directory for temporary files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
=== Cache Files ===&lt;br /&gt;
Symlink: {{path|$KDEHOME/cache-&amp;amp;lt;HOSTNAME&amp;amp;gt;}}&lt;br /&gt;
 &lt;br /&gt;
Default destination: {{path|/var/tmp/kdecache-&amp;amp;lt;USER&amp;amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;cache&amp;lt;/tt&amp;gt; creates a directory for cache files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
The system configuration cache (ksycoca and ksycocastamp) is located in here. It is recommended NOT to delete these files during boot since that will slow down the startup of KDE.&lt;br /&gt;
&lt;br /&gt;
By default this directory is created under &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt;, other locations&lt;br /&gt;
can be used by setting the KDEVARTMP environment variable.&lt;br /&gt;
&lt;br /&gt;
== Adding Lookup Locations ==&lt;br /&gt;
&lt;br /&gt;
KDE applications look up data files using the resource names listed in the&lt;br /&gt;
[#dir_structure Directory Tree] section.  The KDE runtime&lt;br /&gt;
environment translates these names to actual directories&lt;br /&gt;
by combining the locations of the directory trees with the directories&lt;br /&gt;
listed in the tables.&lt;br /&gt;
&lt;br /&gt;
==== Defining Search Paths ====&lt;br /&gt;
&lt;br /&gt;
A user has the following directory tree settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an application now looks for a &amp;quot;wallpaper&amp;quot; file, the directory &amp;quot;share/wallpapers/&amp;quot; is added to each of the&lt;br /&gt;
directory trees. All of the&lt;br /&gt;
resulting directories are then searched for the file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By adding more directory tree to the KDEDIRS environment variable&lt;br /&gt;
it is possible to expand the number of directories that are being searched.&lt;br /&gt;
Sometimes it is desirable to include only a single directory in a search&lt;br /&gt;
but not a whole directory tree. Additional directories can be configured&lt;br /&gt;
in the kdeglobals configuration file in the &amp;quot;Directories&amp;quot; section.&lt;br /&gt;
To do so assign one or more directories to the key &amp;quot;dir_&amp;quot; followed by the&lt;br /&gt;
name of the resource. Multiple directories are separated by commas (,).&lt;br /&gt;
&lt;br /&gt;
==== Adding a Resource Directory ====&lt;br /&gt;
&lt;br /&gt;
To add the directory /data/photos to the wallpaper resource, put the&lt;br /&gt;
following two lines in kdeglobals:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Directories]&lt;br /&gt;
dir_wallpaper=/data/photos&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the application now looks for wallpaper files, it will look in the&lt;br /&gt;
following locations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
/data/photos&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy</id>
		<title>KDE System Administration/KDE Filesystem Hierarchy</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy"/>
				<updated>2010-09-14T12:54:44Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Sockets */ parameter style&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|KDE_System_Administration/KDE_Filesystem_Hierarchy}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
KDE defines a filesystem hierarchy that is used by the KDE environment&lt;br /&gt;
itself as well as all KDE applications. In general, KDE stores all its&lt;br /&gt;
files in a fixed directory tree.&lt;br /&gt;
&lt;br /&gt;
By default, there are two such directory trees: one at the system&lt;br /&gt;
level and one at the user level in the user's home directory. However,&lt;br /&gt;
as a system administrator you can create additional trees.&lt;br /&gt;
&lt;br /&gt;
KDE and KDE applications look up files by scanning the directory trees&lt;br /&gt;
in order of precedence. When a file is&lt;br /&gt;
present in multiple directory trees, the file from the first-listed&lt;br /&gt;
tree takes precedence.&lt;br /&gt;
Normally, the tree located in the user's home directory has the highest&lt;br /&gt;
precedence. This is also the directory tree that changes are&lt;br /&gt;
written to.&lt;br /&gt;
&lt;br /&gt;
For configuration files, the story is slightly&lt;br /&gt;
different. If multiple configuration files with the same name are found in the directory&lt;br /&gt;
trees, their content is combined. The precedence order&lt;br /&gt;
of the directory trees plays a role here: when two files define the same&lt;br /&gt;
configuration key, the file with the highest precedence determines which&lt;br /&gt;
value is used for the key.&lt;br /&gt;
&lt;br /&gt;
== Location of the Directory Trees ==&lt;br /&gt;
&lt;br /&gt;
The location of the KDE Directory Trees is determined by a number of&lt;br /&gt;
environment variables, each of which is covered below.&lt;br /&gt;
&lt;br /&gt;
=== KDEHOME ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;KDEHOME&amp;lt;/tt&amp;gt; environment variable determines the location of the user-level&lt;br /&gt;
directory tree and is used by KDE applications for creating and saving&lt;br /&gt;
files. This directory tree has the highest precedence; files or settings&lt;br /&gt;
found in this directory tree will take precedence over any files or settings&lt;br /&gt;
found in other directory trees.&lt;br /&gt;
&lt;br /&gt;
This directory tree is, as the name suggests, normally located in the user's home directory. If this environment variable is not defined, the default location &amp;lt;tt&amp;gt;$HOME/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; is used.&lt;br /&gt;
&lt;br /&gt;
If the environment variable has a value that starts with a tilde (~), the tilde is replaced with the user's home directory at runtime. In order to use this, care must be taken to add proper quoting, otherwise the shell might do the expansion, resulting in undesired behavior in combination with &amp;lt;tt&amp;gt;su&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== KDEROOTHOME ===&lt;br /&gt;
In order to prevent problems with applications that run as root saving&lt;br /&gt;
files with root access permissions in the user's home directory, the &amp;lt;tt&amp;gt;KDEROOTHOME&amp;lt;/tt&amp;gt;&lt;br /&gt;
environment variable has been introduced in the KDE 3.x series. Applications&lt;br /&gt;
that run with uid 0 (root) will use this variable to determine the location of&lt;br /&gt;
the user level directory and where to save their files. If this variable is&lt;br /&gt;
not defined, the root user's home directory is looked up in the password&lt;br /&gt;
file and .kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt; is appended. Usually that results in &amp;lt;tt&amp;gt;/root/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== KDEDIRS ===&lt;br /&gt;
It is possible to specify multiple system-level directory trees. This allows groups of users to each dedicate a directory to their group. Such an additional directory tree can contain additional applications, specialized application resources or a specific set of default configurations suitable for the group. Specifying default configurations this way instead of using a /etc/skel construction has the advantage that changes in the default configuration can be made after the user's account has been created.&lt;br /&gt;
&lt;br /&gt;
The directories in $KDEDIRS should be separated with a colon (:). The directories are listed in order of precedence: the first directory has the highest precedence, the last one has the lowest precedence.&lt;br /&gt;
&lt;br /&gt;
Since a group-level directory tree should normally override any settings present at the system level, one should list the group-level directory tree before the system level directory tree.&lt;br /&gt;
&lt;br /&gt;
In general communication, references to the directory trees are made in&lt;br /&gt;
terms of $KDEHOME to indicate the applicable user-level directory tree,&lt;br /&gt;
and in terms of $KDEDIRS to indicate any of the system-level directory trees.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
A staff member at a university could have the following settings:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEROOTHOME='/root/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the user settings are saved under the .kde3 directory&lt;br /&gt;
in the user's home directory. Applications that run as root will save their&lt;br /&gt;
settings to /root/.kde3. KDE 3 has been installed to /opt/kde3 but there is&lt;br /&gt;
also an additional directory tree located at /opt/kde_staff. Configuration&lt;br /&gt;
files under that directory will take precedence over the ones in the /opt/kde3&lt;br /&gt;
system directories. /opt/kde_staff could contain additional applications that&lt;br /&gt;
should only be available to staff members.&lt;br /&gt;
&lt;br /&gt;
== Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
Each directory tree used by KDE has a fixed directory structure. However, directories&lt;br /&gt;
that are not relevant for a certain tree can be left out. For example,&lt;br /&gt;
directories used for temporary files are usually only found under $KDEHOME but&lt;br /&gt;
not in any other directory tree.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The KDE runtime environment combines the subdirectories found under the&lt;br /&gt;
various directory trees and refers to them as a single KDE resource. The&lt;br /&gt;
KDE resource name is listed in the tables below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are three broad categories: files that are&lt;br /&gt;
CPU/architecture-specific, files that are host-specific and files that are not specific with&lt;br /&gt;
regard to host, CPU or architecture.&lt;br /&gt;
&lt;br /&gt;
CPU/architecture-specific directories:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|bin/}} || exe || Used for KDE executables.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cgi-bin/}} || cgi || CGI scipts that can be used by the KDE Help Center.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || lib || Used for KDE libraries.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/kde&amp;lt;sub &amp;gt;3&amp;lt;var &amp;gt;&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || module || This directory contains components, plugins and other runtime loadable objects for use by KDE 3.x applications.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following are host-specific directories. They are only available under&lt;br /&gt;
$KDEHOME and are normally symlinked to locations outside the $KDEHOME&lt;br /&gt;
directory tree.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|socket-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Sockets|socket]] || This directory contains communication sockets. The filesystem used by $KDEHOME may not be suitable for communication sockets. For that reason this directory is symlinked to another location by default.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|tmp-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Temporary Files|tmp]] || This directory is used for temporary files. The filesystem used by $KDEHOME may be on a network, so, for performance reasons, this directory is symlinked by default to a location more likely to be on a local filesystem.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cache-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Cache Files|cache]] || New in KDE 3.2. This directory is used for cached information such as HTTP objects, formatted help pages and the system configuration cache (ksycoca).&lt;br /&gt;
&lt;br /&gt;
Since this is non-essential information, this directory is&lt;br /&gt;
symlinked to a location outside $KDEHOME by default to make it easier&lt;br /&gt;
to make backups of other information and reclaim diskspace.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The majority of directories involves data that is not CPU-, architecture- or&lt;br /&gt;
host-specific. All these directories are prefixed with {{path|share/}}:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/applnk/}} || apps || Contains .desktop files describing the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/apps/}} || data || Contains application-specific data files. Each application has a subdirectory here for storing its files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/}} || config || Contains configuration files. Configuration files are normally named after the application they belong to, followed by &amp;quot;rc&amp;quot;. There are also files that are specific to a component and as such referenced by all applications that use that component. A special case is &amp;quot;kdeglobals&amp;quot;: this file is read by all KDE applications.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/session/}} || - || This directory is used by session management and is normally only available under $KDEHOME. At the end of a session, KDE applications store their state here. The file names start with the name of the application followed by a number. The session manager &amp;quot;ksmserver&amp;quot; stores references to these numbers when saving a session in &amp;quot;ksmserverrc&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/doc/HTML/}} || html || Documentation of KDE applications is stored here. Documentation is categorized by language and the application it belongs to. &lt;br /&gt;
&lt;br /&gt;
Normally, at least two files can be found in a directory: &amp;quot;index.docbook&amp;quot;, which contains the documentation in the unformatted docbook format, and &amp;quot;index.cache.bz2&amp;quot;, which contains the same documentation formatted as bzip2 compressed HTML. The HTML version is used by khelpcenter; if the HTML version is missing, it will regenerate it from the docbook version, but this is a time-consuming process.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/icons/}} || icon || Icons are stored under this directory, categorized by theme, dimension and usage category.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mimelnk/}} || mime || Up until KDE4, .desktop files that describe MIME types were stored in this directory.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mime/}} || mime || Starting with KDE4, desktop files that describe MIME types are stored in this directory. This data is shared by other software as well and is part of a freedesktop.org specification.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/services/}}&amp;lt;br&amp;gt;{{path|share/kde4/services/}} || services || This directory contains .desktop files that describe services. Services and Applications are very similar; the major difference is that a Service is usually used by other Services or Applications, while an Application is in general started by the user. Services do not appear in the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/servicetypes/}}&amp;lt;br&amp;gt;{{path|share/kde4/servicetypes/}} || servicetypes || This directory contains .desktop files that describe service types. A service type usually represents a certain programming interface. Applications and Services include the servicetypes that they provide in their .desktop files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/sounds/}} || sound || This directory contains sound files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/templates/}} || templates || This directory contains templates for creating files of various types. A template consists of a .desktop file that describes the file and includes a reference to a file in the .source subdirectory. The templates in this directory appear in the &amp;quot;Create New&amp;quot; menu available on the desktop and in the file browser. When a user selects a template from the menu, its source file is copied.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/wallpapers/}} || wallpaper || This directory contains images that can be used as background pictures.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Outside the Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
As mentioned in the description of the directory tree, there are three host-specific directories that are usually symlinked to other locations. If the directories do not already exist, the following symlinks and directories will be created using the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility. Since both &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt; are world writable, there is a possibility that one of the mentioned directories already exists but is owned by another user. In that case, the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility will create a new directory with an alternative name and link to that instead.&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
Symlink: {{path|&amp;lt;VAR &amp;gt;$KDEHOME&amp;lt;/VAR &amp;gt;/socket-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/ksocket-&amp;lt;VAR &amp;gt;$USER&amp;lt;/VAR &amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;socket&amp;lt;/tt&amp;gt; creates a directory for local communication sockets and point a symlink to it. The combined length of the directory name and the name of any communication socket should not exceed 106 characters. By default this directory is created under &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt;, but other locations can be used by setting the KDETMP environment variable.&lt;br /&gt;
&lt;br /&gt;
=== Temporary Files ===&lt;br /&gt;
Symlink: {{path|$KDEHOME/tmp-&amp;amp;lt;HOSTNAME&amp;amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/kde-&amp;amp;lt;USER&amp;amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;tmp&amp;lt;/tt&amp;gt; creates a directory for temporary files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
=== Cache Files ===&lt;br /&gt;
Symlink: {{path|$KDEHOME/cache-&amp;amp;lt;HOSTNAME&amp;amp;gt;}}&lt;br /&gt;
 &lt;br /&gt;
Default destination: {{path|/var/tmp/kdecache-&amp;amp;lt;USER&amp;amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;cache&amp;lt;/tt&amp;gt; creates a directory for cache files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
The system configuration cache (ksycoca and ksycocastamp) is located in here. It is recommended NOT to delete these files during boot since that will slow down the startup of KDE.&lt;br /&gt;
&lt;br /&gt;
By default this directory is created under &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt;, other locations&lt;br /&gt;
can be used by setting the KDEVARTMP environment variable.&lt;br /&gt;
&lt;br /&gt;
== Adding Lookup Locations ==&lt;br /&gt;
&lt;br /&gt;
KDE applications look up data files using the resource names listed in the&lt;br /&gt;
[#dir_structure Directory Tree] section.  The KDE runtime&lt;br /&gt;
environment translates these names to actual directories&lt;br /&gt;
by combining the locations of the directory trees with the directories&lt;br /&gt;
listed in the tables.&lt;br /&gt;
&lt;br /&gt;
==== Defining Search Paths ====&lt;br /&gt;
&lt;br /&gt;
A user has the following directory tree settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an application now looks for a &amp;quot;wallpaper&amp;quot; file, the directory &amp;quot;share/wallpapers/&amp;quot; is added to each of the&lt;br /&gt;
directory trees. All of the&lt;br /&gt;
resulting directories are then searched for the file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By adding more directory tree to the KDEDIRS environment variable&lt;br /&gt;
it is possible to expand the number of directories that are being searched.&lt;br /&gt;
Sometimes it is desirable to include only a single directory in a search&lt;br /&gt;
but not a whole directory tree. Additional directories can be configured&lt;br /&gt;
in the kdeglobals configuration file in the &amp;quot;Directories&amp;quot; section.&lt;br /&gt;
To do so assign one or more directories to the key &amp;quot;dir_&amp;quot; followed by the&lt;br /&gt;
name of the resource. Multiple directories are separated by commas (,).&lt;br /&gt;
&lt;br /&gt;
==== Adding a Resource Directory ====&lt;br /&gt;
&lt;br /&gt;
To add the directory /data/photos to the wallpaper resource, put the&lt;br /&gt;
following two lines in kdeglobals:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Directories]&lt;br /&gt;
dir_wallpaper=/data/photos&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the application now looks for wallpaper files, it will look in the&lt;br /&gt;
following locations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
/data/photos&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy</id>
		<title>KDE System Administration/KDE Filesystem Hierarchy</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy"/>
				<updated>2010-09-14T12:51:54Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Directory Tree */ links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|KDE_System_Administration/KDE_Filesystem_Hierarchy}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
KDE defines a filesystem hierarchy that is used by the KDE environment&lt;br /&gt;
itself as well as all KDE applications. In general, KDE stores all its&lt;br /&gt;
files in a fixed directory tree.&lt;br /&gt;
&lt;br /&gt;
By default, there are two such directory trees: one at the system&lt;br /&gt;
level and one at the user level in the user's home directory. However,&lt;br /&gt;
as a system administrator you can create additional trees.&lt;br /&gt;
&lt;br /&gt;
KDE and KDE applications look up files by scanning the directory trees&lt;br /&gt;
in order of precedence. When a file is&lt;br /&gt;
present in multiple directory trees, the file from the first-listed&lt;br /&gt;
tree takes precedence.&lt;br /&gt;
Normally, the tree located in the user's home directory has the highest&lt;br /&gt;
precedence. This is also the directory tree that changes are&lt;br /&gt;
written to.&lt;br /&gt;
&lt;br /&gt;
For configuration files, the story is slightly&lt;br /&gt;
different. If multiple configuration files with the same name are found in the directory&lt;br /&gt;
trees, their content is combined. The precedence order&lt;br /&gt;
of the directory trees plays a role here: when two files define the same&lt;br /&gt;
configuration key, the file with the highest precedence determines which&lt;br /&gt;
value is used for the key.&lt;br /&gt;
&lt;br /&gt;
== Location of the Directory Trees ==&lt;br /&gt;
&lt;br /&gt;
The location of the KDE Directory Trees is determined by a number of&lt;br /&gt;
environment variables, each of which is covered below.&lt;br /&gt;
&lt;br /&gt;
=== KDEHOME ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;KDEHOME&amp;lt;/tt&amp;gt; environment variable determines the location of the user-level&lt;br /&gt;
directory tree and is used by KDE applications for creating and saving&lt;br /&gt;
files. This directory tree has the highest precedence; files or settings&lt;br /&gt;
found in this directory tree will take precedence over any files or settings&lt;br /&gt;
found in other directory trees.&lt;br /&gt;
&lt;br /&gt;
This directory tree is, as the name suggests, normally located in the user's home directory. If this environment variable is not defined, the default location &amp;lt;tt&amp;gt;$HOME/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; is used.&lt;br /&gt;
&lt;br /&gt;
If the environment variable has a value that starts with a tilde (~), the tilde is replaced with the user's home directory at runtime. In order to use this, care must be taken to add proper quoting, otherwise the shell might do the expansion, resulting in undesired behavior in combination with &amp;lt;tt&amp;gt;su&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== KDEROOTHOME ===&lt;br /&gt;
In order to prevent problems with applications that run as root saving&lt;br /&gt;
files with root access permissions in the user's home directory, the &amp;lt;tt&amp;gt;KDEROOTHOME&amp;lt;/tt&amp;gt;&lt;br /&gt;
environment variable has been introduced in the KDE 3.x series. Applications&lt;br /&gt;
that run with uid 0 (root) will use this variable to determine the location of&lt;br /&gt;
the user level directory and where to save their files. If this variable is&lt;br /&gt;
not defined, the root user's home directory is looked up in the password&lt;br /&gt;
file and .kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt; is appended. Usually that results in &amp;lt;tt&amp;gt;/root/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== KDEDIRS ===&lt;br /&gt;
It is possible to specify multiple system-level directory trees. This allows groups of users to each dedicate a directory to their group. Such an additional directory tree can contain additional applications, specialized application resources or a specific set of default configurations suitable for the group. Specifying default configurations this way instead of using a /etc/skel construction has the advantage that changes in the default configuration can be made after the user's account has been created.&lt;br /&gt;
&lt;br /&gt;
The directories in $KDEDIRS should be separated with a colon (:). The directories are listed in order of precedence: the first directory has the highest precedence, the last one has the lowest precedence.&lt;br /&gt;
&lt;br /&gt;
Since a group-level directory tree should normally override any settings present at the system level, one should list the group-level directory tree before the system level directory tree.&lt;br /&gt;
&lt;br /&gt;
In general communication, references to the directory trees are made in&lt;br /&gt;
terms of $KDEHOME to indicate the applicable user-level directory tree,&lt;br /&gt;
and in terms of $KDEDIRS to indicate any of the system-level directory trees.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
A staff member at a university could have the following settings:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEROOTHOME='/root/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the user settings are saved under the .kde3 directory&lt;br /&gt;
in the user's home directory. Applications that run as root will save their&lt;br /&gt;
settings to /root/.kde3. KDE 3 has been installed to /opt/kde3 but there is&lt;br /&gt;
also an additional directory tree located at /opt/kde_staff. Configuration&lt;br /&gt;
files under that directory will take precedence over the ones in the /opt/kde3&lt;br /&gt;
system directories. /opt/kde_staff could contain additional applications that&lt;br /&gt;
should only be available to staff members.&lt;br /&gt;
&lt;br /&gt;
== Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
Each directory tree used by KDE has a fixed directory structure. However, directories&lt;br /&gt;
that are not relevant for a certain tree can be left out. For example,&lt;br /&gt;
directories used for temporary files are usually only found under $KDEHOME but&lt;br /&gt;
not in any other directory tree.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The KDE runtime environment combines the subdirectories found under the&lt;br /&gt;
various directory trees and refers to them as a single KDE resource. The&lt;br /&gt;
KDE resource name is listed in the tables below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are three broad categories: files that are&lt;br /&gt;
CPU/architecture-specific, files that are host-specific and files that are not specific with&lt;br /&gt;
regard to host, CPU or architecture.&lt;br /&gt;
&lt;br /&gt;
CPU/architecture-specific directories:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|bin/}} || exe || Used for KDE executables.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cgi-bin/}} || cgi || CGI scipts that can be used by the KDE Help Center.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || lib || Used for KDE libraries.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/kde&amp;lt;sub &amp;gt;3&amp;lt;var &amp;gt;&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || module || This directory contains components, plugins and other runtime loadable objects for use by KDE 3.x applications.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following are host-specific directories. They are only available under&lt;br /&gt;
$KDEHOME and are normally symlinked to locations outside the $KDEHOME&lt;br /&gt;
directory tree.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|socket-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Sockets|socket]] || This directory contains communication sockets. The filesystem used by $KDEHOME may not be suitable for communication sockets. For that reason this directory is symlinked to another location by default.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|tmp-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Temporary Files|tmp]] || This directory is used for temporary files. The filesystem used by $KDEHOME may be on a network, so, for performance reasons, this directory is symlinked by default to a location more likely to be on a local filesystem.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cache-&amp;lt;VAR &amp;gt;$HOSTNAME&amp;lt;/VAR &amp;gt;}} || [[#Cache Files|cache]] || New in KDE 3.2. This directory is used for cached information such as HTTP objects, formatted help pages and the system configuration cache (ksycoca).&lt;br /&gt;
&lt;br /&gt;
Since this is non-essential information, this directory is&lt;br /&gt;
symlinked to a location outside $KDEHOME by default to make it easier&lt;br /&gt;
to make backups of other information and reclaim diskspace.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The majority of directories involves data that is not CPU-, architecture- or&lt;br /&gt;
host-specific. All these directories are prefixed with {{path|share/}}:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/applnk/}} || apps || Contains .desktop files describing the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/apps/}} || data || Contains application-specific data files. Each application has a subdirectory here for storing its files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/}} || config || Contains configuration files. Configuration files are normally named after the application they belong to, followed by &amp;quot;rc&amp;quot;. There are also files that are specific to a component and as such referenced by all applications that use that component. A special case is &amp;quot;kdeglobals&amp;quot;: this file is read by all KDE applications.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/session/}} || - || This directory is used by session management and is normally only available under $KDEHOME. At the end of a session, KDE applications store their state here. The file names start with the name of the application followed by a number. The session manager &amp;quot;ksmserver&amp;quot; stores references to these numbers when saving a session in &amp;quot;ksmserverrc&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/doc/HTML/}} || html || Documentation of KDE applications is stored here. Documentation is categorized by language and the application it belongs to. &lt;br /&gt;
&lt;br /&gt;
Normally, at least two files can be found in a directory: &amp;quot;index.docbook&amp;quot;, which contains the documentation in the unformatted docbook format, and &amp;quot;index.cache.bz2&amp;quot;, which contains the same documentation formatted as bzip2 compressed HTML. The HTML version is used by khelpcenter; if the HTML version is missing, it will regenerate it from the docbook version, but this is a time-consuming process.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/icons/}} || icon || Icons are stored under this directory, categorized by theme, dimension and usage category.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mimelnk/}} || mime || Up until KDE4, .desktop files that describe MIME types were stored in this directory.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mime/}} || mime || Starting with KDE4, desktop files that describe MIME types are stored in this directory. This data is shared by other software as well and is part of a freedesktop.org specification.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/services/}}&amp;lt;br&amp;gt;{{path|share/kde4/services/}} || services || This directory contains .desktop files that describe services. Services and Applications are very similar; the major difference is that a Service is usually used by other Services or Applications, while an Application is in general started by the user. Services do not appear in the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/servicetypes/}}&amp;lt;br&amp;gt;{{path|share/kde4/servicetypes/}} || servicetypes || This directory contains .desktop files that describe service types. A service type usually represents a certain programming interface. Applications and Services include the servicetypes that they provide in their .desktop files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/sounds/}} || sound || This directory contains sound files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/templates/}} || templates || This directory contains templates for creating files of various types. A template consists of a .desktop file that describes the file and includes a reference to a file in the .source subdirectory. The templates in this directory appear in the &amp;quot;Create New&amp;quot; menu available on the desktop and in the file browser. When a user selects a template from the menu, its source file is copied.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/wallpapers/}} || wallpaper || This directory contains images that can be used as background pictures.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Outside the Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
As mentioned in the description of the directory tree, there are three host-specific directories that are usually symlinked to other locations. If the directories do not already exist, the following symlinks and directories will be created using the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility. Since both &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt; are world writable, there is a possibility that one of the mentioned directories already exists but is owned by another user. In that case, the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility will create a new directory with an alternative name and link to that instead.&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
Symlink: {{path|$KDEHOME/socket-&amp;amp;lt;HOSTNAME&amp;amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/ksocket-&amp;amp;lt;USER&amp;amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;socket&amp;lt;/tt&amp;gt; creates a directory for local communication sockets and point a symlink to it. The combined length of the directory name and the name of any communication socket should not exceed 106 characters. By default this directory is created under &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt;, but other locations can be used by setting the KDETMP environment variable.&lt;br /&gt;
&lt;br /&gt;
=== Temporary Files ===&lt;br /&gt;
Symlink: {{path|$KDEHOME/tmp-&amp;amp;lt;HOSTNAME&amp;amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/kde-&amp;amp;lt;USER&amp;amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;tmp&amp;lt;/tt&amp;gt; creates a directory for temporary files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
=== Cache Files ===&lt;br /&gt;
Symlink: {{path|$KDEHOME/cache-&amp;amp;lt;HOSTNAME&amp;amp;gt;}}&lt;br /&gt;
 &lt;br /&gt;
Default destination: {{path|/var/tmp/kdecache-&amp;amp;lt;USER&amp;amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;cache&amp;lt;/tt&amp;gt; creates a directory for cache files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
The system configuration cache (ksycoca and ksycocastamp) is located in here. It is recommended NOT to delete these files during boot since that will slow down the startup of KDE.&lt;br /&gt;
&lt;br /&gt;
By default this directory is created under &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt;, other locations&lt;br /&gt;
can be used by setting the KDEVARTMP environment variable.&lt;br /&gt;
&lt;br /&gt;
== Adding Lookup Locations ==&lt;br /&gt;
&lt;br /&gt;
KDE applications look up data files using the resource names listed in the&lt;br /&gt;
[#dir_structure Directory Tree] section.  The KDE runtime&lt;br /&gt;
environment translates these names to actual directories&lt;br /&gt;
by combining the locations of the directory trees with the directories&lt;br /&gt;
listed in the tables.&lt;br /&gt;
&lt;br /&gt;
==== Defining Search Paths ====&lt;br /&gt;
&lt;br /&gt;
A user has the following directory tree settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an application now looks for a &amp;quot;wallpaper&amp;quot; file, the directory &amp;quot;share/wallpapers/&amp;quot; is added to each of the&lt;br /&gt;
directory trees. All of the&lt;br /&gt;
resulting directories are then searched for the file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By adding more directory tree to the KDEDIRS environment variable&lt;br /&gt;
it is possible to expand the number of directories that are being searched.&lt;br /&gt;
Sometimes it is desirable to include only a single directory in a search&lt;br /&gt;
but not a whole directory tree. Additional directories can be configured&lt;br /&gt;
in the kdeglobals configuration file in the &amp;quot;Directories&amp;quot; section.&lt;br /&gt;
To do so assign one or more directories to the key &amp;quot;dir_&amp;quot; followed by the&lt;br /&gt;
name of the resource. Multiple directories are separated by commas (,).&lt;br /&gt;
&lt;br /&gt;
==== Adding a Resource Directory ====&lt;br /&gt;
&lt;br /&gt;
To add the directory /data/photos to the wallpaper resource, put the&lt;br /&gt;
following two lines in kdeglobals:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Directories]&lt;br /&gt;
dir_wallpaper=/data/photos&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the application now looks for wallpaper files, it will look in the&lt;br /&gt;
following locations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
/data/photos&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy</id>
		<title>KDE System Administration/KDE Filesystem Hierarchy</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy"/>
				<updated>2010-09-14T12:45:15Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Directory Tree */ variants&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|KDE_System_Administration/KDE_Filesystem_Hierarchy}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
KDE defines a filesystem hierarchy that is used by the KDE environment&lt;br /&gt;
itself as well as all KDE applications. In general, KDE stores all its&lt;br /&gt;
files in a fixed directory tree.&lt;br /&gt;
&lt;br /&gt;
By default, there are two such directory trees: one at the system&lt;br /&gt;
level and one at the user level in the user's home directory. However,&lt;br /&gt;
as a system administrator you can create additional trees.&lt;br /&gt;
&lt;br /&gt;
KDE and KDE applications look up files by scanning the directory trees&lt;br /&gt;
in order of precedence. When a file is&lt;br /&gt;
present in multiple directory trees, the file from the first-listed&lt;br /&gt;
tree takes precedence.&lt;br /&gt;
Normally, the tree located in the user's home directory has the highest&lt;br /&gt;
precedence. This is also the directory tree that changes are&lt;br /&gt;
written to.&lt;br /&gt;
&lt;br /&gt;
For configuration files, the story is slightly&lt;br /&gt;
different. If multiple configuration files with the same name are found in the directory&lt;br /&gt;
trees, their content is combined. The precedence order&lt;br /&gt;
of the directory trees plays a role here: when two files define the same&lt;br /&gt;
configuration key, the file with the highest precedence determines which&lt;br /&gt;
value is used for the key.&lt;br /&gt;
&lt;br /&gt;
== Location of the Directory Trees ==&lt;br /&gt;
&lt;br /&gt;
The location of the KDE Directory Trees is determined by a number of&lt;br /&gt;
environment variables, each of which is covered below.&lt;br /&gt;
&lt;br /&gt;
=== KDEHOME ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;KDEHOME&amp;lt;/tt&amp;gt; environment variable determines the location of the user-level&lt;br /&gt;
directory tree and is used by KDE applications for creating and saving&lt;br /&gt;
files. This directory tree has the highest precedence; files or settings&lt;br /&gt;
found in this directory tree will take precedence over any files or settings&lt;br /&gt;
found in other directory trees.&lt;br /&gt;
&lt;br /&gt;
This directory tree is, as the name suggests, normally located in the user's home directory. If this environment variable is not defined, the default location &amp;lt;tt&amp;gt;$HOME/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; is used.&lt;br /&gt;
&lt;br /&gt;
If the environment variable has a value that starts with a tilde (~), the tilde is replaced with the user's home directory at runtime. In order to use this, care must be taken to add proper quoting, otherwise the shell might do the expansion, resulting in undesired behavior in combination with &amp;lt;tt&amp;gt;su&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== KDEROOTHOME ===&lt;br /&gt;
In order to prevent problems with applications that run as root saving&lt;br /&gt;
files with root access permissions in the user's home directory, the &amp;lt;tt&amp;gt;KDEROOTHOME&amp;lt;/tt&amp;gt;&lt;br /&gt;
environment variable has been introduced in the KDE 3.x series. Applications&lt;br /&gt;
that run with uid 0 (root) will use this variable to determine the location of&lt;br /&gt;
the user level directory and where to save their files. If this variable is&lt;br /&gt;
not defined, the root user's home directory is looked up in the password&lt;br /&gt;
file and .kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt; is appended. Usually that results in &amp;lt;tt&amp;gt;/root/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== KDEDIRS ===&lt;br /&gt;
It is possible to specify multiple system-level directory trees. This allows groups of users to each dedicate a directory to their group. Such an additional directory tree can contain additional applications, specialized application resources or a specific set of default configurations suitable for the group. Specifying default configurations this way instead of using a /etc/skel construction has the advantage that changes in the default configuration can be made after the user's account has been created.&lt;br /&gt;
&lt;br /&gt;
The directories in $KDEDIRS should be separated with a colon (:). The directories are listed in order of precedence: the first directory has the highest precedence, the last one has the lowest precedence.&lt;br /&gt;
&lt;br /&gt;
Since a group-level directory tree should normally override any settings present at the system level, one should list the group-level directory tree before the system level directory tree.&lt;br /&gt;
&lt;br /&gt;
In general communication, references to the directory trees are made in&lt;br /&gt;
terms of $KDEHOME to indicate the applicable user-level directory tree,&lt;br /&gt;
and in terms of $KDEDIRS to indicate any of the system-level directory trees.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
A staff member at a university could have the following settings:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEROOTHOME='/root/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the user settings are saved under the .kde3 directory&lt;br /&gt;
in the user's home directory. Applications that run as root will save their&lt;br /&gt;
settings to /root/.kde3. KDE 3 has been installed to /opt/kde3 but there is&lt;br /&gt;
also an additional directory tree located at /opt/kde_staff. Configuration&lt;br /&gt;
files under that directory will take precedence over the ones in the /opt/kde3&lt;br /&gt;
system directories. /opt/kde_staff could contain additional applications that&lt;br /&gt;
should only be available to staff members.&lt;br /&gt;
&lt;br /&gt;
== Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
Each directory tree used by KDE has a fixed directory structure. However, directories&lt;br /&gt;
that are not relevant for a certain tree can be left out. For example,&lt;br /&gt;
directories used for temporary files are usually only found under $KDEHOME but&lt;br /&gt;
not in any other directory tree.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The KDE runtime environment combines the subdirectories found under the&lt;br /&gt;
various directory trees and refers to them as a single KDE resource. The&lt;br /&gt;
KDE resource name is listed in the tables below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are three broad categories: files that are&lt;br /&gt;
CPU/architecture-specific, files that are host-specific and files that are not specific with&lt;br /&gt;
regard to host, CPU or architecture.&lt;br /&gt;
&lt;br /&gt;
CPU/architecture-specific directories:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|bin/}} || exe || Used for KDE executables.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cgi-bin/}} || cgi || CGI scipts that can be used by the KDE Help Center.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || lib || Used for KDE libraries.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;64&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/kde&amp;lt;sub &amp;gt;3&amp;lt;var &amp;gt;&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;/}} || module || This directory contains components, plugins and other runtime loadable objects for use by KDE 3.x applications.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following are host-specific directories. They are only available under&lt;br /&gt;
$KDEHOME and are normally symlinked to locations outside the $KDEHOME&lt;br /&gt;
directory tree.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|socket-&amp;amp;lt;HOSTNAME&amp;amp;gt;}} || socket || This directory contains communication sockets. The filesystem used by $KDEHOME may not be suitable for communication sockets. For that reason this directory is symlinked to another location by default.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|tmp-&amp;amp;lt;HOSTNAME&amp;amp;gt;}} || tmp || This directory is used for temporary files. The filesystem used by $KDEHOME may be on a network, so, for performance reasons, this directory is symlinked by default to a location more likely to be on a local filesystem.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cache-&amp;amp;lt;HOSTNAME&amp;amp;gt;}} || cache || New in KDE 3.2. This directory is used for cached information such as HTTP objects, formatted help pages and the system configuration cache (ksycoca).&lt;br /&gt;
&lt;br /&gt;
Since this is non-essential information, this directory is&lt;br /&gt;
symlinked to a location outside $KDEHOME by default to make it easier&lt;br /&gt;
to make backups of other information and reclaim diskspace.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The majority of directories involves data that is not CPU-, architecture- or&lt;br /&gt;
host-specific. All these directories are prefixed with {{path|share/}}:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/applnk/}} || apps || Contains .desktop files describing the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/apps/}} || data || Contains application-specific data files. Each application has a subdirectory here for storing its files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/}} || config || Contains configuration files. Configuration files are normally named after the application they belong to, followed by &amp;quot;rc&amp;quot;. There are also files that are specific to a component and as such referenced by all applications that use that component. A special case is &amp;quot;kdeglobals&amp;quot;: this file is read by all KDE applications.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/session/}} || - || This directory is used by session management and is normally only available under $KDEHOME. At the end of a session, KDE applications store their state here. The file names start with the name of the application followed by a number. The session manager &amp;quot;ksmserver&amp;quot; stores references to these numbers when saving a session in &amp;quot;ksmserverrc&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/doc/HTML/}} || html || Documentation of KDE applications is stored here. Documentation is categorized by language and the application it belongs to. &lt;br /&gt;
&lt;br /&gt;
Normally, at least two files can be found in a directory: &amp;quot;index.docbook&amp;quot;, which contains the documentation in the unformatted docbook format, and &amp;quot;index.cache.bz2&amp;quot;, which contains the same documentation formatted as bzip2 compressed HTML. The HTML version is used by khelpcenter; if the HTML version is missing, it will regenerate it from the docbook version, but this is a time-consuming process.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/icons/}} || icon || Icons are stored under this directory, categorized by theme, dimension and usage category.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mimelnk/}} || mime || Up until KDE4, .desktop files that describe MIME types were stored in this directory.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mime/}} || mime || Starting with KDE4, desktop files that describe MIME types are stored in this directory. This data is shared by other software as well and is part of a freedesktop.org specification.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/services/}}&amp;lt;br&amp;gt;{{path|share/kde4/services/}} || services || This directory contains .desktop files that describe services. Services and Applications are very similar; the major difference is that a Service is usually used by other Services or Applications, while an Application is in general started by the user. Services do not appear in the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/servicetypes/}}&amp;lt;br&amp;gt;{{path|share/kde4/servicetypes/}} || servicetypes || This directory contains .desktop files that describe service types. A service type usually represents a certain programming interface. Applications and Services include the servicetypes that they provide in their .desktop files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/sounds/}} || sound || This directory contains sound files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/templates/}} || templates || This directory contains templates for creating files of various types. A template consists of a .desktop file that describes the file and includes a reference to a file in the .source subdirectory. The templates in this directory appear in the &amp;quot;Create New&amp;quot; menu available on the desktop and in the file browser. When a user selects a template from the menu, its source file is copied.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/wallpapers/}} || wallpaper || This directory contains images that can be used as background pictures.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Outside the Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
As mentioned in the description of the directory tree, there are three host-specific directories that are usually symlinked to other locations. If the directories do not already exist, the following symlinks and directories will be created using the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility. Since both &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt; are world writable, there is a possibility that one of the mentioned directories already exists but is owned by another user. In that case, the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility will create a new directory with an alternative name and link to that instead.&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
Symlink: {{path|$KDEHOME/socket-&amp;amp;lt;HOSTNAME&amp;amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/ksocket-&amp;amp;lt;USER&amp;amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;socket&amp;lt;/tt&amp;gt; creates a directory for local communication sockets and point a symlink to it. The combined length of the directory name and the name of any communication socket should not exceed 106 characters. By default this directory is created under &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt;, but other locations can be used by setting the KDETMP environment variable.&lt;br /&gt;
&lt;br /&gt;
=== Temporary Files ===&lt;br /&gt;
Symlink: {{path|$KDEHOME/tmp-&amp;amp;lt;HOSTNAME&amp;amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/kde-&amp;amp;lt;USER&amp;amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;tmp&amp;lt;/tt&amp;gt; creates a directory for temporary files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
=== Cache Files ===&lt;br /&gt;
Symlink: {{path|$KDEHOME/cache-&amp;amp;lt;HOSTNAME&amp;amp;gt;}}&lt;br /&gt;
 &lt;br /&gt;
Default destination: {{path|/var/tmp/kdecache-&amp;amp;lt;USER&amp;amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;cache&amp;lt;/tt&amp;gt; creates a directory for cache files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
The system configuration cache (ksycoca and ksycocastamp) is located in here. It is recommended NOT to delete these files during boot since that will slow down the startup of KDE.&lt;br /&gt;
&lt;br /&gt;
By default this directory is created under &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt;, other locations&lt;br /&gt;
can be used by setting the KDEVARTMP environment variable.&lt;br /&gt;
&lt;br /&gt;
== Adding Lookup Locations ==&lt;br /&gt;
&lt;br /&gt;
KDE applications look up data files using the resource names listed in the&lt;br /&gt;
[#dir_structure Directory Tree] section.  The KDE runtime&lt;br /&gt;
environment translates these names to actual directories&lt;br /&gt;
by combining the locations of the directory trees with the directories&lt;br /&gt;
listed in the tables.&lt;br /&gt;
&lt;br /&gt;
==== Defining Search Paths ====&lt;br /&gt;
&lt;br /&gt;
A user has the following directory tree settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an application now looks for a &amp;quot;wallpaper&amp;quot; file, the directory &amp;quot;share/wallpapers/&amp;quot; is added to each of the&lt;br /&gt;
directory trees. All of the&lt;br /&gt;
resulting directories are then searched for the file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By adding more directory tree to the KDEDIRS environment variable&lt;br /&gt;
it is possible to expand the number of directories that are being searched.&lt;br /&gt;
Sometimes it is desirable to include only a single directory in a search&lt;br /&gt;
but not a whole directory tree. Additional directories can be configured&lt;br /&gt;
in the kdeglobals configuration file in the &amp;quot;Directories&amp;quot; section.&lt;br /&gt;
To do so assign one or more directories to the key &amp;quot;dir_&amp;quot; followed by the&lt;br /&gt;
name of the resource. Multiple directories are separated by commas (,).&lt;br /&gt;
&lt;br /&gt;
==== Adding a Resource Directory ====&lt;br /&gt;
&lt;br /&gt;
To add the directory /data/photos to the wallpaper resource, put the&lt;br /&gt;
following two lines in kdeglobals:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Directories]&lt;br /&gt;
dir_wallpaper=/data/photos&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the application now looks for wallpaper files, it will look in the&lt;br /&gt;
following locations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
/data/photos&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy</id>
		<title>KDE System Administration/KDE Filesystem Hierarchy</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy"/>
				<updated>2010-09-14T12:34:14Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* KDEROOTHOME */ &amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|KDE_System_Administration/KDE_Filesystem_Hierarchy}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
KDE defines a filesystem hierarchy that is used by the KDE environment&lt;br /&gt;
itself as well as all KDE applications. In general, KDE stores all its&lt;br /&gt;
files in a fixed directory tree.&lt;br /&gt;
&lt;br /&gt;
By default, there are two such directory trees: one at the system&lt;br /&gt;
level and one at the user level in the user's home directory. However,&lt;br /&gt;
as a system administrator you can create additional trees.&lt;br /&gt;
&lt;br /&gt;
KDE and KDE applications look up files by scanning the directory trees&lt;br /&gt;
in order of precedence. When a file is&lt;br /&gt;
present in multiple directory trees, the file from the first-listed&lt;br /&gt;
tree takes precedence.&lt;br /&gt;
Normally, the tree located in the user's home directory has the highest&lt;br /&gt;
precedence. This is also the directory tree that changes are&lt;br /&gt;
written to.&lt;br /&gt;
&lt;br /&gt;
For configuration files, the story is slightly&lt;br /&gt;
different. If multiple configuration files with the same name are found in the directory&lt;br /&gt;
trees, their content is combined. The precedence order&lt;br /&gt;
of the directory trees plays a role here: when two files define the same&lt;br /&gt;
configuration key, the file with the highest precedence determines which&lt;br /&gt;
value is used for the key.&lt;br /&gt;
&lt;br /&gt;
== Location of the Directory Trees ==&lt;br /&gt;
&lt;br /&gt;
The location of the KDE Directory Trees is determined by a number of&lt;br /&gt;
environment variables, each of which is covered below.&lt;br /&gt;
&lt;br /&gt;
=== KDEHOME ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;KDEHOME&amp;lt;/tt&amp;gt; environment variable determines the location of the user-level&lt;br /&gt;
directory tree and is used by KDE applications for creating and saving&lt;br /&gt;
files. This directory tree has the highest precedence; files or settings&lt;br /&gt;
found in this directory tree will take precedence over any files or settings&lt;br /&gt;
found in other directory trees.&lt;br /&gt;
&lt;br /&gt;
This directory tree is, as the name suggests, normally located in the user's home directory. If this environment variable is not defined, the default location &amp;lt;tt&amp;gt;$HOME/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; is used.&lt;br /&gt;
&lt;br /&gt;
If the environment variable has a value that starts with a tilde (~), the tilde is replaced with the user's home directory at runtime. In order to use this, care must be taken to add proper quoting, otherwise the shell might do the expansion, resulting in undesired behavior in combination with &amp;lt;tt&amp;gt;su&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== KDEROOTHOME ===&lt;br /&gt;
In order to prevent problems with applications that run as root saving&lt;br /&gt;
files with root access permissions in the user's home directory, the &amp;lt;tt&amp;gt;KDEROOTHOME&amp;lt;/tt&amp;gt;&lt;br /&gt;
environment variable has been introduced in the KDE 3.x series. Applications&lt;br /&gt;
that run with uid 0 (root) will use this variable to determine the location of&lt;br /&gt;
the user level directory and where to save their files. If this variable is&lt;br /&gt;
not defined, the root user's home directory is looked up in the password&lt;br /&gt;
file and .kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt; is appended. Usually that results in &amp;lt;tt&amp;gt;/root/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== KDEDIRS ===&lt;br /&gt;
It is possible to specify multiple system-level directory trees. This allows groups of users to each dedicate a directory to their group. Such an additional directory tree can contain additional applications, specialized application resources or a specific set of default configurations suitable for the group. Specifying default configurations this way instead of using a /etc/skel construction has the advantage that changes in the default configuration can be made after the user's account has been created.&lt;br /&gt;
&lt;br /&gt;
The directories in $KDEDIRS should be separated with a colon (:). The directories are listed in order of precedence: the first directory has the highest precedence, the last one has the lowest precedence.&lt;br /&gt;
&lt;br /&gt;
Since a group-level directory tree should normally override any settings present at the system level, one should list the group-level directory tree before the system level directory tree.&lt;br /&gt;
&lt;br /&gt;
In general communication, references to the directory trees are made in&lt;br /&gt;
terms of $KDEHOME to indicate the applicable user-level directory tree,&lt;br /&gt;
and in terms of $KDEDIRS to indicate any of the system-level directory trees.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
A staff member at a university could have the following settings:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEROOTHOME='/root/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the user settings are saved under the .kde3 directory&lt;br /&gt;
in the user's home directory. Applications that run as root will save their&lt;br /&gt;
settings to /root/.kde3. KDE 3 has been installed to /opt/kde3 but there is&lt;br /&gt;
also an additional directory tree located at /opt/kde_staff. Configuration&lt;br /&gt;
files under that directory will take precedence over the ones in the /opt/kde3&lt;br /&gt;
system directories. /opt/kde_staff could contain additional applications that&lt;br /&gt;
should only be available to staff members.&lt;br /&gt;
&lt;br /&gt;
== Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
Each directory tree used by KDE has a fixed directory structure. However, directories&lt;br /&gt;
that are not relevant for a certain tree can be left out. For example,&lt;br /&gt;
directories used for temporary files are usually only found under $KDEHOME but&lt;br /&gt;
not in any other directory tree.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The KDE runtime environment combines the subdirectories found under the&lt;br /&gt;
various directory trees and refers to them as a single KDE resource. The&lt;br /&gt;
KDE resource name is listed in the tables below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are three broad categories: files that are&lt;br /&gt;
CPU/architecture-specific, files that are host-specific and files that are not specific with&lt;br /&gt;
regard to host, CPU or architecture.&lt;br /&gt;
&lt;br /&gt;
CPU/architecture-specific directories:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|bin/}} || exe || Used for KDE executables.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cgi-bin/}} || cgi || CGI scipts that can be used by the KDE Help Center.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib/}} || lib || Used for KDE libraries.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib/kde3/}} || module || This directory contains components, plugins and other runtime loadable objects for use by KDE 3.x applications.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following are host-specific directories. They are only available under&lt;br /&gt;
$KDEHOME and are normally symlinked to locations outside the $KDEHOME&lt;br /&gt;
directory tree.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|socket-&amp;amp;lt;HOSTNAME&amp;amp;gt;}} || socket || This directory contains communication sockets. The filesystem used by $KDEHOME may not be suitable for communication sockets. For that reason this directory is symlinked to another location by default.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|tmp-&amp;amp;lt;HOSTNAME&amp;amp;gt;}} || tmp || This directory is used for temporary files. The filesystem used by $KDEHOME may be on a network, so, for performance reasons, this directory is symlinked by default to a location more likely to be on a local filesystem.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cache-&amp;amp;lt;HOSTNAME&amp;amp;gt;}} || cache || New in KDE 3.2. This directory is used for cached information such as HTTP objects, formatted help pages and the system configuration cache (ksycoca).&lt;br /&gt;
&lt;br /&gt;
Since this is non-essential information, this directory is&lt;br /&gt;
symlinked to a location outside $KDEHOME by default to make it easier&lt;br /&gt;
to make backups of other information and reclaim diskspace.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The majority of directories involves data that is not CPU-, architecture- or&lt;br /&gt;
host-specific. All these directories are prefixed with {{path|share/}}:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/applnk/}} || apps || Contains .desktop files describing the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/apps/}} || data || Contains application-specific data files. Each application has a subdirectory here for storing its files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/}} || config || Contains configuration files. Configuration files are normally named after the application they belong to, followed by &amp;quot;rc&amp;quot;. There are also files that are specific to a component and as such referenced by all applications that use that component. A special case is &amp;quot;kdeglobals&amp;quot;: this file is read by all KDE applications.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/session/}} || - || This directory is used by session management and is normally only available under $KDEHOME. At the end of a session, KDE applications store their state here. The file names start with the name of the application followed by a number. The session manager &amp;quot;ksmserver&amp;quot; stores references to these numbers when saving a session in &amp;quot;ksmserverrc&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/doc/HTML/}} || html || Documentation of KDE applications is stored here. Documentation is categorized by language and the application it belongs to. &lt;br /&gt;
&lt;br /&gt;
Normally, at least two files can be found in a directory: &amp;quot;index.docbook&amp;quot;, which contains the documentation in the unformatted docbook format, and &amp;quot;index.cache.bz2&amp;quot;, which contains the same documentation formatted as bzip2 compressed HTML. The HTML version is used by khelpcenter; if the HTML version is missing, it will regenerate it from the docbook version, but this is a time-consuming process.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/icons/}} || icon || Icons are stored under this directory, categorized by theme, dimension and usage category.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mimelnk/}} || mime || Up until KDE4, .desktop files that describe MIME types were stored in this directory.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mime/}} || mime || Starting with KDE4, desktop files that describe MIME types are stored in this directory. This data is shared by other software as well and is part of a freedesktop.org specification.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/services/}}&amp;lt;br&amp;gt;{{path|share/kde4/services/}} || services || This directory contains .desktop files that describe services. Services and Applications are very similar; the major difference is that a Service is usually used by other Services or Applications, while an Application is in general started by the user. Services do not appear in the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/servicetypes/}}&amp;lt;br&amp;gt;{{path|share/kde4/servicetypes/}} || servicetypes || This directory contains .desktop files that describe service types. A service type usually represents a certain programming interface. Applications and Services include the servicetypes that they provide in their .desktop files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/sounds/}} || sound || This directory contains sound files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/templates/}} || templates || This directory contains templates for creating files of various types. A template consists of a .desktop file that describes the file and includes a reference to a file in the .source subdirectory. The templates in this directory appear in the &amp;quot;Create New&amp;quot; menu available on the desktop and in the file browser. When a user selects a template from the menu, its source file is copied.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/wallpapers/}} || wallpaper || This directory contains images that can be used as background pictures.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Outside the Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
As mentioned in the description of the directory tree, there are three host-specific directories that are usually symlinked to other locations. If the directories do not already exist, the following symlinks and directories will be created using the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility. Since both &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt; are world writable, there is a possibility that one of the mentioned directories already exists but is owned by another user. In that case, the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility will create a new directory with an alternative name and link to that instead.&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
Symlink: {{path|$KDEHOME/socket-&amp;amp;lt;HOSTNAME&amp;amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/ksocket-&amp;amp;lt;USER&amp;amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;socket&amp;lt;/tt&amp;gt; creates a directory for local communication sockets and point a symlink to it. The combined length of the directory name and the name of any communication socket should not exceed 106 characters. By default this directory is created under &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt;, but other locations can be used by setting the KDETMP environment variable.&lt;br /&gt;
&lt;br /&gt;
=== Temporary Files ===&lt;br /&gt;
Symlink: {{path|$KDEHOME/tmp-&amp;amp;lt;HOSTNAME&amp;amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/kde-&amp;amp;lt;USER&amp;amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;tmp&amp;lt;/tt&amp;gt; creates a directory for temporary files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
=== Cache Files ===&lt;br /&gt;
Symlink: {{path|$KDEHOME/cache-&amp;amp;lt;HOSTNAME&amp;amp;gt;}}&lt;br /&gt;
 &lt;br /&gt;
Default destination: {{path|/var/tmp/kdecache-&amp;amp;lt;USER&amp;amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;cache&amp;lt;/tt&amp;gt; creates a directory for cache files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
The system configuration cache (ksycoca and ksycocastamp) is located in here. It is recommended NOT to delete these files during boot since that will slow down the startup of KDE.&lt;br /&gt;
&lt;br /&gt;
By default this directory is created under &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt;, other locations&lt;br /&gt;
can be used by setting the KDEVARTMP environment variable.&lt;br /&gt;
&lt;br /&gt;
== Adding Lookup Locations ==&lt;br /&gt;
&lt;br /&gt;
KDE applications look up data files using the resource names listed in the&lt;br /&gt;
[#dir_structure Directory Tree] section.  The KDE runtime&lt;br /&gt;
environment translates these names to actual directories&lt;br /&gt;
by combining the locations of the directory trees with the directories&lt;br /&gt;
listed in the tables.&lt;br /&gt;
&lt;br /&gt;
==== Defining Search Paths ====&lt;br /&gt;
&lt;br /&gt;
A user has the following directory tree settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an application now looks for a &amp;quot;wallpaper&amp;quot; file, the directory &amp;quot;share/wallpapers/&amp;quot; is added to each of the&lt;br /&gt;
directory trees. All of the&lt;br /&gt;
resulting directories are then searched for the file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By adding more directory tree to the KDEDIRS environment variable&lt;br /&gt;
it is possible to expand the number of directories that are being searched.&lt;br /&gt;
Sometimes it is desirable to include only a single directory in a search&lt;br /&gt;
but not a whole directory tree. Additional directories can be configured&lt;br /&gt;
in the kdeglobals configuration file in the &amp;quot;Directories&amp;quot; section.&lt;br /&gt;
To do so assign one or more directories to the key &amp;quot;dir_&amp;quot; followed by the&lt;br /&gt;
name of the resource. Multiple directories are separated by commas (,).&lt;br /&gt;
&lt;br /&gt;
==== Adding a Resource Directory ====&lt;br /&gt;
&lt;br /&gt;
To add the directory /data/photos to the wallpaper resource, put the&lt;br /&gt;
following two lines in kdeglobals:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Directories]&lt;br /&gt;
dir_wallpaper=/data/photos&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the application now looks for wallpaper files, it will look in the&lt;br /&gt;
following locations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
/data/photos&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy</id>
		<title>KDE System Administration/KDE Filesystem Hierarchy</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/KDE_System_Administration/KDE_Filesystem_Hierarchy"/>
				<updated>2010-09-14T12:32:22Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* KDEHOME */ kde&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|KDE_System_Administration/KDE_Filesystem_Hierarchy}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
KDE defines a filesystem hierarchy that is used by the KDE environment&lt;br /&gt;
itself as well as all KDE applications. In general, KDE stores all its&lt;br /&gt;
files in a fixed directory tree.&lt;br /&gt;
&lt;br /&gt;
By default, there are two such directory trees: one at the system&lt;br /&gt;
level and one at the user level in the user's home directory. However,&lt;br /&gt;
as a system administrator you can create additional trees.&lt;br /&gt;
&lt;br /&gt;
KDE and KDE applications look up files by scanning the directory trees&lt;br /&gt;
in order of precedence. When a file is&lt;br /&gt;
present in multiple directory trees, the file from the first-listed&lt;br /&gt;
tree takes precedence.&lt;br /&gt;
Normally, the tree located in the user's home directory has the highest&lt;br /&gt;
precedence. This is also the directory tree that changes are&lt;br /&gt;
written to.&lt;br /&gt;
&lt;br /&gt;
For configuration files, the story is slightly&lt;br /&gt;
different. If multiple configuration files with the same name are found in the directory&lt;br /&gt;
trees, their content is combined. The precedence order&lt;br /&gt;
of the directory trees plays a role here: when two files define the same&lt;br /&gt;
configuration key, the file with the highest precedence determines which&lt;br /&gt;
value is used for the key.&lt;br /&gt;
&lt;br /&gt;
== Location of the Directory Trees ==&lt;br /&gt;
&lt;br /&gt;
The location of the KDE Directory Trees is determined by a number of&lt;br /&gt;
environment variables, each of which is covered below.&lt;br /&gt;
&lt;br /&gt;
=== KDEHOME ===&lt;br /&gt;
The &amp;lt;tt&amp;gt;KDEHOME&amp;lt;/tt&amp;gt; environment variable determines the location of the user-level&lt;br /&gt;
directory tree and is used by KDE applications for creating and saving&lt;br /&gt;
files. This directory tree has the highest precedence; files or settings&lt;br /&gt;
found in this directory tree will take precedence over any files or settings&lt;br /&gt;
found in other directory trees.&lt;br /&gt;
&lt;br /&gt;
This directory tree is, as the name suggests, normally located in the user's home directory. If this environment variable is not defined, the default location &amp;lt;tt&amp;gt;$HOME/.kde&amp;lt;sub &amp;gt;&amp;lt;var &amp;gt;4&amp;lt;/var &amp;gt;&amp;lt;/sub &amp;gt;&amp;lt;/tt&amp;gt; is used.&lt;br /&gt;
&lt;br /&gt;
If the environment variable has a value that starts with a tilde (~), the tilde is replaced with the user's home directory at runtime. In order to use this, care must be taken to add proper quoting, otherwise the shell might do the expansion, resulting in undesired behavior in combination with &amp;lt;tt&amp;gt;su&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== KDEROOTHOME ===&lt;br /&gt;
In order to prevent problems with applications that run as root saving&lt;br /&gt;
files with root access permissions in the user's home directory, the &amp;lt;tt&amp;gt;KDEROOTHOME&amp;lt;/tt&amp;gt;&lt;br /&gt;
environment variable has been introduced in the KDE 3.x series. Applications&lt;br /&gt;
that run with uid 0 (root) will use this variable to determine the location of&lt;br /&gt;
the user level directory and where to save their files. If this variable is&lt;br /&gt;
not defined, the root user's home directory is looked up in the password&lt;br /&gt;
file and .kde is appended. Usually that results in &amp;lt;tt&amp;gt;/root/.kde&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
=== KDEDIRS ===&lt;br /&gt;
It is possible to specify multiple system-level directory trees. This allows groups of users to each dedicate a directory to their group. Such an additional directory tree can contain additional applications, specialized application resources or a specific set of default configurations suitable for the group. Specifying default configurations this way instead of using a /etc/skel construction has the advantage that changes in the default configuration can be made after the user's account has been created.&lt;br /&gt;
&lt;br /&gt;
The directories in $KDEDIRS should be separated with a colon (:). The directories are listed in order of precedence: the first directory has the highest precedence, the last one has the lowest precedence.&lt;br /&gt;
&lt;br /&gt;
Since a group-level directory tree should normally override any settings present at the system level, one should list the group-level directory tree before the system level directory tree.&lt;br /&gt;
&lt;br /&gt;
In general communication, references to the directory trees are made in&lt;br /&gt;
terms of $KDEHOME to indicate the applicable user-level directory tree,&lt;br /&gt;
and in terms of $KDEDIRS to indicate any of the system-level directory trees.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
A staff member at a university could have the following settings:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEROOTHOME='/root/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the user settings are saved under the .kde3 directory&lt;br /&gt;
in the user's home directory. Applications that run as root will save their&lt;br /&gt;
settings to /root/.kde3. KDE 3 has been installed to /opt/kde3 but there is&lt;br /&gt;
also an additional directory tree located at /opt/kde_staff. Configuration&lt;br /&gt;
files under that directory will take precedence over the ones in the /opt/kde3&lt;br /&gt;
system directories. /opt/kde_staff could contain additional applications that&lt;br /&gt;
should only be available to staff members.&lt;br /&gt;
&lt;br /&gt;
== Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
Each directory tree used by KDE has a fixed directory structure. However, directories&lt;br /&gt;
that are not relevant for a certain tree can be left out. For example,&lt;br /&gt;
directories used for temporary files are usually only found under $KDEHOME but&lt;br /&gt;
not in any other directory tree.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The KDE runtime environment combines the subdirectories found under the&lt;br /&gt;
various directory trees and refers to them as a single KDE resource. The&lt;br /&gt;
KDE resource name is listed in the tables below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are three broad categories: files that are&lt;br /&gt;
CPU/architecture-specific, files that are host-specific and files that are not specific with&lt;br /&gt;
regard to host, CPU or architecture.&lt;br /&gt;
&lt;br /&gt;
CPU/architecture-specific directories:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|bin/}} || exe || Used for KDE executables.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cgi-bin/}} || cgi || CGI scipts that can be used by the KDE Help Center.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib/}} || lib || Used for KDE libraries.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|lib/kde3/}} || module || This directory contains components, plugins and other runtime loadable objects for use by KDE 3.x applications.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The following are host-specific directories. They are only available under&lt;br /&gt;
$KDEHOME and are normally symlinked to locations outside the $KDEHOME&lt;br /&gt;
directory tree.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|socket-&amp;amp;lt;HOSTNAME&amp;amp;gt;}} || socket || This directory contains communication sockets. The filesystem used by $KDEHOME may not be suitable for communication sockets. For that reason this directory is symlinked to another location by default.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|tmp-&amp;amp;lt;HOSTNAME&amp;amp;gt;}} || tmp || This directory is used for temporary files. The filesystem used by $KDEHOME may be on a network, so, for performance reasons, this directory is symlinked by default to a location more likely to be on a local filesystem.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|cache-&amp;amp;lt;HOSTNAME&amp;amp;gt;}} || cache || New in KDE 3.2. This directory is used for cached information such as HTTP objects, formatted help pages and the system configuration cache (ksycoca).&lt;br /&gt;
&lt;br /&gt;
Since this is non-essential information, this directory is&lt;br /&gt;
symlinked to a location outside $KDEHOME by default to make it easier&lt;br /&gt;
to make backups of other information and reclaim diskspace.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The majority of directories involves data that is not CPU-, architecture- or&lt;br /&gt;
host-specific. All these directories are prefixed with {{path|share/}}:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Directory !! KDE&amp;amp;nbsp;resource !! Description&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/applnk/}} || apps || Contains .desktop files describing the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/apps/}} || data || Contains application-specific data files. Each application has a subdirectory here for storing its files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/}} || config || Contains configuration files. Configuration files are normally named after the application they belong to, followed by &amp;quot;rc&amp;quot;. There are also files that are specific to a component and as such referenced by all applications that use that component. A special case is &amp;quot;kdeglobals&amp;quot;: this file is read by all KDE applications.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/config/session/}} || - || This directory is used by session management and is normally only available under $KDEHOME. At the end of a session, KDE applications store their state here. The file names start with the name of the application followed by a number. The session manager &amp;quot;ksmserver&amp;quot; stores references to these numbers when saving a session in &amp;quot;ksmserverrc&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/doc/HTML/}} || html || Documentation of KDE applications is stored here. Documentation is categorized by language and the application it belongs to. &lt;br /&gt;
&lt;br /&gt;
Normally, at least two files can be found in a directory: &amp;quot;index.docbook&amp;quot;, which contains the documentation in the unformatted docbook format, and &amp;quot;index.cache.bz2&amp;quot;, which contains the same documentation formatted as bzip2 compressed HTML. The HTML version is used by khelpcenter; if the HTML version is missing, it will regenerate it from the docbook version, but this is a time-consuming process.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/icons/}} || icon || Icons are stored under this directory, categorized by theme, dimension and usage category.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mimelnk/}} || mime || Up until KDE4, .desktop files that describe MIME types were stored in this directory.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/mime/}} || mime || Starting with KDE4, desktop files that describe MIME types are stored in this directory. This data is shared by other software as well and is part of a freedesktop.org specification.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/services/}}&amp;lt;br&amp;gt;{{path|share/kde4/services/}} || services || This directory contains .desktop files that describe services. Services and Applications are very similar; the major difference is that a Service is usually used by other Services or Applications, while an Application is in general started by the user. Services do not appear in the KDE menu.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/servicetypes/}}&amp;lt;br&amp;gt;{{path|share/kde4/servicetypes/}} || servicetypes || This directory contains .desktop files that describe service types. A service type usually represents a certain programming interface. Applications and Services include the servicetypes that they provide in their .desktop files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/sounds/}} || sound || This directory contains sound files.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/templates/}} || templates || This directory contains templates for creating files of various types. A template consists of a .desktop file that describes the file and includes a reference to a file in the .source subdirectory. The templates in this directory appear in the &amp;quot;Create New&amp;quot; menu available on the desktop and in the file browser. When a user selects a template from the menu, its source file is copied.&lt;br /&gt;
|-&lt;br /&gt;
| {{path|share/wallpapers/}} || wallpaper || This directory contains images that can be used as background pictures.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Outside the Directory Tree ==&lt;br /&gt;
&lt;br /&gt;
As mentioned in the description of the directory tree, there are three host-specific directories that are usually symlinked to other locations. If the directories do not already exist, the following symlinks and directories will be created using the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility. Since both &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt; are world writable, there is a possibility that one of the mentioned directories already exists but is owned by another user. In that case, the &amp;lt;tt&amp;gt;lnusertemp&amp;lt;/tt&amp;gt; utility will create a new directory with an alternative name and link to that instead.&lt;br /&gt;
&lt;br /&gt;
=== Sockets ===&lt;br /&gt;
Symlink: {{path|$KDEHOME/socket-&amp;amp;lt;HOSTNAME&amp;amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/ksocket-&amp;amp;lt;USER&amp;amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;socket&amp;lt;/tt&amp;gt; creates a directory for local communication sockets and point a symlink to it. The combined length of the directory name and the name of any communication socket should not exceed 106 characters. By default this directory is created under &amp;lt;tt&amp;gt;/tmp&amp;lt;/tt&amp;gt;, but other locations can be used by setting the KDETMP environment variable.&lt;br /&gt;
&lt;br /&gt;
=== Temporary Files ===&lt;br /&gt;
Symlink: {{path|$KDEHOME/tmp-&amp;amp;lt;HOSTNAME&amp;amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Default destination: {{path|/tmp/kde-&amp;amp;lt;USER&amp;amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;tmp&amp;lt;/tt&amp;gt; creates a directory for temporary files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
=== Cache Files ===&lt;br /&gt;
Symlink: {{path|$KDEHOME/cache-&amp;amp;lt;HOSTNAME&amp;amp;gt;}}&lt;br /&gt;
 &lt;br /&gt;
Default destination: {{path|/var/tmp/kdecache-&amp;amp;lt;USER&amp;amp;gt;/}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;lnusertemp&amp;amp;nbsp;cache&amp;lt;/tt&amp;gt; creates a directory for cache files and points a symlink to it. For performance reasons it is recommended to have this directory on a local filesystem, but this is not strictly necessary.&lt;br /&gt;
&lt;br /&gt;
The system configuration cache (ksycoca and ksycocastamp) is located in here. It is recommended NOT to delete these files during boot since that will slow down the startup of KDE.&lt;br /&gt;
&lt;br /&gt;
By default this directory is created under &amp;lt;tt&amp;gt;/var/tmp&amp;lt;/tt&amp;gt;, other locations&lt;br /&gt;
can be used by setting the KDEVARTMP environment variable.&lt;br /&gt;
&lt;br /&gt;
== Adding Lookup Locations ==&lt;br /&gt;
&lt;br /&gt;
KDE applications look up data files using the resource names listed in the&lt;br /&gt;
[#dir_structure Directory Tree] section.  The KDE runtime&lt;br /&gt;
environment translates these names to actual directories&lt;br /&gt;
by combining the locations of the directory trees with the directories&lt;br /&gt;
listed in the tables.&lt;br /&gt;
&lt;br /&gt;
==== Defining Search Paths ====&lt;br /&gt;
&lt;br /&gt;
A user has the following directory tree settings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
KDEHOME='~/.kde3'&lt;br /&gt;
KDEDIRS='/opt/kde_staff:/opt/kde3'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an application now looks for a &amp;quot;wallpaper&amp;quot; file, the directory &amp;quot;share/wallpapers/&amp;quot; is added to each of the&lt;br /&gt;
directory trees. All of the&lt;br /&gt;
resulting directories are then searched for the file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By adding more directory tree to the KDEDIRS environment variable&lt;br /&gt;
it is possible to expand the number of directories that are being searched.&lt;br /&gt;
Sometimes it is desirable to include only a single directory in a search&lt;br /&gt;
but not a whole directory tree. Additional directories can be configured&lt;br /&gt;
in the kdeglobals configuration file in the &amp;quot;Directories&amp;quot; section.&lt;br /&gt;
To do so assign one or more directories to the key &amp;quot;dir_&amp;quot; followed by the&lt;br /&gt;
name of the resource. Multiple directories are separated by commas (,).&lt;br /&gt;
&lt;br /&gt;
==== Adding a Resource Directory ====&lt;br /&gt;
&lt;br /&gt;
To add the directory /data/photos to the wallpaper resource, put the&lt;br /&gt;
following two lines in kdeglobals:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
[Directories]&lt;br /&gt;
dir_wallpaper=/data/photos&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the application now looks for wallpaper files, it will look in the&lt;br /&gt;
following locations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
/data/photos&lt;br /&gt;
~/.kde3/share/wallpapers/&lt;br /&gt;
/opt/kde_staff/share/wallpapers/&lt;br /&gt;
/opt/kde3/share/wallpapers/&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/File:Shell_Scripting_with_KDE_Dialogs_passivepopup_dlg.png</id>
		<title>File:Shell Scripting with KDE Dialogs passivepopup dlg.png</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/File:Shell_Scripting_with_KDE_Dialogs_passivepopup_dlg.png"/>
				<updated>2010-09-13T19:01:05Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: Window screen shot of the passive popup kdialog example [1].
Created with GIMP
___
[1] &amp;lt;URL:http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs#Example_11._--passivepopup_dialog_box&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Window screen shot of the passive popup kdialog example [1].&lt;br /&gt;
Created with GIMP&lt;br /&gt;
___&lt;br /&gt;
[1] &amp;lt;URL:http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs#Example_11._--passivepopup_dialog_box&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Debugging/How_to_create_useful_crash_reports</id>
		<title>Development/Tutorials/Debugging/How to create useful crash reports</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Debugging/How_to_create_useful_crash_reports"/>
				<updated>2010-09-12T21:37:45Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Preparing your KDE packages */ openSUSE migrated&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Tutorials/Debugging/How to create useful crash reports}}&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
This document describes how to reproduce a useful backtrace of crashing KDE applications. First, some general information is given. Then, we will describe for several distributions how to prepare your KDE packages and gaining the backtrace. This should be enough for most people.&lt;br /&gt;
There are additional sections on how to create backtraces with the GNU Debugger and with Valgrind, which are in some cases useful.&lt;br /&gt;
&lt;br /&gt;
==How to create useful crash reports==&lt;br /&gt;
&lt;br /&gt;
A good crash report at [http://bugs.kde.org Bugzilla] consists of two parts: a '''description''' of how to reproduce the crash and a '''backtrace''' of the crash. With one of those elements missing, it is much harder (if not impossible) for developers to tackle the problem.&lt;br /&gt;
&lt;br /&gt;
A description should consist of more than only &amp;amp;quot;it crashed&amp;amp;quot;. Try to describe everything you did prior to the crash. Did you click on a button, opened a particular website or file which caused problems? That little detail which may look useless to you may be useful for the developer, so just write it down.&lt;br /&gt;
&lt;br /&gt;
A more insightful article on how to write good bug descriptions is available [http://www.chiark.greenend.org.uk/~sgtatham/bugs.html at this link], please read that before reporting bugs.&lt;br /&gt;
&lt;br /&gt;
Don't attach the backtrace to the bug report. Instead, simply paste it. This way it is much easier for developers to search for duplicate reports, because attachments will not be searched.&lt;br /&gt;
&lt;br /&gt;
If you paste a backtrace to a report, make sure you strip all but one or two of the &lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
lines from the backtrace as they make it harder to read.&lt;br /&gt;
&lt;br /&gt;
Even though pasting backtraces directly is preferred over adding an attachment, please do not paste other things like logs (valgrind, strace or terminal output) or example data (mails, HTML files and so on). Use attachments for these items.&lt;br /&gt;
&lt;br /&gt;
===Backtraces===&lt;br /&gt;
&lt;br /&gt;
Backtraces are essential. They may look meaningless to you, but they might actually contain a wealth of useful information. A backtrace describes which functions were called prior to the crash, so that developers may track down in which function the mess started. Having good backtraces has a downside: [[Development/Tutorials/Debugging/Debugging_symbols|libraries and executables occupy much more disk space than their optimized counter parts]]. That's the reason why many distros choose to install stripped files, '''which results in useless backtraces''':&lt;br /&gt;
&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 Using host libthread_db library &amp;quot;/lib/tls/i686/cmov/libthread_db.so.1&amp;quot;.&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 [Thread debugging using libthread_db enabled]&lt;br /&gt;
 [New Thread -1233848624 (LWP 12212)]&lt;br /&gt;
 [New Thread -1255081072 (LWP 12820)]&lt;br /&gt;
 [New Thread -1240921200 (LWP 12819)]&lt;br /&gt;
 [New Thread -1266680944 (LWP 12818)]&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 (no debugging symbols found)&lt;br /&gt;
 0xffffe410 in __kernel_vsyscall ()&lt;br /&gt;
 #0  0xffffe410 in __kernel_vsyscall ()&lt;br /&gt;
 #1  0xb6a1210b in ?? () from /lib/tls/i686/cmov/libpthread.so.0&lt;br /&gt;
 #2  0xb6a85afe in ?? () from /usr/lib/libX11.so.6&lt;br /&gt;
 #3  0x00000003 in ?? ()&lt;br /&gt;
 #4  0x082149c0 in ?? ()&lt;br /&gt;
 #5  0x00003ffc in ?? ()&lt;br /&gt;
 #6  0x00000000 in ?? ()&lt;br /&gt;
&lt;br /&gt;
But no worries, with some modifications you can create full blown backtraces for KDE applications.&lt;br /&gt;
&lt;br /&gt;
===Preparing your KDE packages===&lt;br /&gt;
&lt;br /&gt;
If your distribution has debugging-enabled packages, install them.&lt;br /&gt;
&lt;br /&gt;
It is easy to see which debug packages you are missing from looking at the backtrace. For example, take the following line from a backtrace:&lt;br /&gt;
&lt;br /&gt;
 #6  0xb7975bdc in ?? () from /usr/lib/libkmailprivate.so.4&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;??&amp;lt;/tt&amp;gt; indicates that the library &amp;lt;tt&amp;gt;libkmailprivate.so.4&amp;lt;/tt&amp;gt; does not have debug information, which might be available in separate debug packages. In this case, it is pretty easy to guess that you need to install debug packages for KMail to get a better backtrace.&lt;br /&gt;
&lt;br /&gt;
Sometimes, you need to install more than one debug package to get a good backtrace. This depends on how the distribution splits up the packages. For example, for some distributions it is enough to install the debug package for &amp;lt;tt&amp;gt;kdepim&amp;lt;/tt&amp;gt; to get enough debugging information for a crash in KMail, for other distributions there is an additional debug package just for KMail.&lt;br /&gt;
&lt;br /&gt;
Here's a list of how to obtain debug packages for some distributions:&lt;br /&gt;
&lt;br /&gt;
*'''Debian''' - Debian offers &amp;lt;tt&amp;gt;-dbg&amp;lt;/tt&amp;gt; packages to easy create useful backtraces. Just install the corresponding &amp;lt;tt&amp;gt;-dbg&amp;lt;/tt&amp;gt; package. e.g. &amp;lt;tt&amp;gt;kdepim-dbg&amp;lt;/tt&amp;gt; for KMail crashes. The dependencies of -dbg makes sure to pull in the other right packages (kdelibs-dbg, gdb, and so on).&lt;br /&gt;
*'''FreeBSD ports''' - Please refer to the [http://freebsd.kde.org/faq.php#AKDEapplicationcrashedandIwanttofileabugreportathttpbugskdeorgbutthebacktraceintheKDECrashManagerisuselessWhatcanIdo KDE on FreeBSD FAQ].&lt;br /&gt;
*'''Gentoo''' - Gentoo has its [http://www.gentoo.org/proj/en/qa/backtraces.xml own document] describing how to proceed.&lt;br /&gt;
*'''Mandriva''' - Mandriva 2007.0 and up has additional debugging packages for all of KDE (in fact, for all of its packages). Just install the corresponding &amp;lt;tt&amp;gt;-debug&amp;lt;/tt&amp;gt; package, like &amp;lt;tt&amp;gt;kdebase-debug&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;kdemultimedia-debug&amp;lt;/tt&amp;gt;. You probably want to install &amp;lt;tt&amp;gt;kdelibs-debug&amp;lt;/tt&amp;gt; anyways.&lt;br /&gt;
** Note: the &amp;lt;tt&amp;gt;-debug&amp;lt;/tt&amp;gt; packages are in separate repositories. For instance, for all packages in &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;, you'll find the debugging package in repository &amp;lt;tt&amp;gt;debug_main&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*'''Kubuntu/Ubuntu''' - The Ubuntu family makes things quite easy. Every official KDE module has an additional package in the repository, suffixed with &amp;lt;tt&amp;gt;-dbg&amp;lt;/tt&amp;gt;. Always install &amp;lt;tt&amp;gt;kdelibs5-dbg&amp;lt;/tt&amp;gt;, because all KDE applications use kdelibs (kdelibs-dbg for KDE 3 applications). Then you should install a -dbg package for the application which crashed. For example if KOrganizer crashed you should install &amp;lt;tt&amp;gt;kdepim-dbg&amp;lt;/tt&amp;gt; as well.  If the program is not from an official KDE module and has no -dbg package, you can install the -dbgsym package from the repository listed on this [https://wiki.kubuntu.org/DebuggingProgramCrash Debugging Program Crashes] page.  &lt;br /&gt;
**During the Ubuntu development cycle the Apport crash handler is turned on which will report crashes to launchpad.net and do the backtrace for you, if you would rather use the KDE crash handler turn Apport off in /etc/defaults/apport&lt;br /&gt;
**Starting with Lucid Lynx (10.04) Kubuntu will be forwarding all non kubuntu specific bugs upstream and had disabled Apport so that DrKonqui will be th edefault crash handler.&lt;br /&gt;
*'''openSUSE''' - You should only install the &amp;lt;tt&amp;gt;-debuginfo&amp;lt;/tt&amp;gt; packages, for example: &amp;lt;tt&amp;gt;kdepimlibs4-debuginfo&amp;lt;/tt&amp;gt;. You can find these packages in [http://en.opensuse.org/KDE/Repositories KDE repositories]. There is also a dedicated [http://en.opensuse.org/openSUSE:Bugreport_application_crashed openSUSE debugging page].&lt;br /&gt;
*'''Fedora''' - In Fedora you just need to do:&lt;br /&gt;
*# &amp;lt;tt&amp;gt;yum provides &amp;quot;/usr/lib/libkmailprivate.so.4&amp;quot;&amp;lt;/tt&amp;gt; to find out which package provides that file;&lt;br /&gt;
*# &amp;lt;tt&amp;gt;debuginfo-install kdepim&amp;lt;/tt&amp;gt; as root to install debug packages for that package (dependencies included).&lt;br /&gt;
*:A complete and detailed guide for Fedora is available in [http://fedoraproject.org/wiki/StackTraces this document] describing how to proceed. Fedora uses a separate debuginfo repository that has to be enabled. Also consider &amp;lt;tt&amp;gt;auto-update-debug-info&amp;lt;/tt&amp;gt; yum plugin to keep debuginfo packages up to date.&lt;br /&gt;
&lt;br /&gt;
If your distribution doesn't have debugging-enabled packages for KDE, you'll have to compile KDE from sources:&lt;br /&gt;
&lt;br /&gt;
* If you're using KDE 3, then at the configure stage, you should supply the parameter &amp;lt;tt&amp;gt;--enable-debug=full&amp;lt;/tt&amp;gt; in order to build debug symbols in the resulting files.&lt;br /&gt;
* If you're using KDE 4, then at the cmake stage, you should supply the parameter &amp;lt;tt&amp;gt;-DCMAKE_BUILD_TYPE=debugfull&amp;lt;/tt&amp;gt;.  If you want to specify your own CXXFLAGS, then use &amp;lt;tt&amp;gt;-DCMAKE_BUILD_TYPE=None CMAKE_CXX_FLAGS=&amp;quot;-O0 -g&amp;quot;&amp;lt;/tt&amp;gt;.  You can change the CMAKE_CXX_FLAGS as appropriate for your needs.&lt;br /&gt;
&lt;br /&gt;
Then it's just &amp;lt;tt&amp;gt;make&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;make install&amp;lt;/tt&amp;gt; as you're used to.&lt;br /&gt;
&lt;br /&gt;
===Crash!===&lt;br /&gt;
&lt;br /&gt;
Now it's time to crash your application. The KDE Crash Dialog should appear right after the crash, which shows the Backtrace tab.&lt;br /&gt;
&lt;br /&gt;
[[Image:Kde-crash-handler.png|center|300px|KDE Crash Dialog]]&lt;br /&gt;
&lt;br /&gt;
Click that tab and wait for a minute. This process may take quite some memory, so things may go sluggish all of a sudden. But the result should look much better. For example:&lt;br /&gt;
&lt;br /&gt;
 Using host libthread_db library &amp;quot;/lib/libthread_db.so.1&amp;quot;. &lt;br /&gt;
 [Thread debugging using libthread_db enabled] &lt;br /&gt;
 [New Thread -1232783168 (LWP 7604)] &lt;br /&gt;
 [KCrash handler] &lt;br /&gt;
 #6  0x0806be76 in TreeMapItem::parent (this=0x0) &lt;br /&gt;
     at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/treemap.h:285 &lt;br /&gt;
 #7  0x08065fea in TreeMapItemList::compareItems (this=0xbfec04a8, item1=0x0, &lt;br /&gt;
     item2=0x0) &lt;br /&gt;
     at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/treemap.cpp:720 &lt;br /&gt;
 #8  0xb7281619 in QGList::operator== () from /usr/qt/3/lib/libqt-mt.so.3 &lt;br /&gt;
 #9  0x0806d498 in QPtrList&amp;lt;TreeMapItem&amp;gt;::operator== (this=0xbfec04a8, &lt;br /&gt;
     list=@0xbfec0468) at /usr/qt/3/include/qptrlist.h:74 &lt;br /&gt;
 #10 0x08062e18 in TreeMapWidget::mousePressEvent (this=0xbfec03ac, &lt;br /&gt;
     e=0xbfebff1c) &lt;br /&gt;
     at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/treemap.cpp:1840 &lt;br /&gt;
 #11 0xb7004a63 in QWidget::event () from /usr/qt/3/lib/libqt-mt.so.3 &lt;br /&gt;
 #12 0xb6f6bca7 in QApplication::internalNotify () &lt;br /&gt;
    from /usr/qt/3/lib/libqt-mt.so.3 &lt;br /&gt;
 #13 0xb6f6ca88 in QApplication::notify () from /usr/qt/3/lib/libqt-mt.so.3 &lt;br /&gt;
 #14 0xb7725a84 in KApplication::notify (this=0xbfec055c, receiver=0xbfec03ac, &lt;br /&gt;
     event=0xbfebff1c) &lt;br /&gt;
     at /home/bram/KDE/kde3/kdelibs/kdecore/kapplication.cpp:550 &lt;br /&gt;
 #15 0xb6f0bfd2 in QETWidget::translateMouseEvent () &lt;br /&gt;
    from /usr/qt/3/lib/libqt-mt.so.3 &lt;br /&gt;
 #16 0xb6f0b8b0 in QApplication::x11ProcessEvent () &lt;br /&gt;
    from /usr/qt/3/lib/libqt-mt.so.3 &lt;br /&gt;
 #17 0xb6f1b761 in QEventLoop::processEvents () from /usr/qt/3/lib/libqt-mt.so.3 &lt;br /&gt;
 #18 0xb6f82831 in QEventLoop::enterLoop () from /usr/qt/3/lib/libqt-mt.so.3 &lt;br /&gt;
 #19 0xb6f826b6 in QEventLoop::exec () from /usr/qt/3/lib/libqt-mt.so.3 &lt;br /&gt;
 #20 0xb6f6b72f in QApplication::exec () from /usr/qt/3/lib/libqt-mt.so.3 &lt;br /&gt;
 #21 0x0805181e in main (argc=134673960, argv=0xffffffff) &lt;br /&gt;
     at /home/bram/KDE/kde3/kdeaddons/konq-plugins/fsview/main.cpp:55&lt;br /&gt;
&lt;br /&gt;
This looks better, right? It shows memory addresses, the source files and line numbers and the parameters passed to functions. Which make it more helpful to the developer where to look for the problem.&lt;br /&gt;
&lt;br /&gt;
{{note|You '''need''' GDB installed to get the backtrace of a crash. Please read the next section to know what GDB is, and how to install it.}}&lt;br /&gt;
&lt;br /&gt;
===Retrieving a backtrace with GDB===&lt;br /&gt;
&lt;br /&gt;
In some cases, it is not possible to create a backtrace with the KDE Crash Dialog. This may be caused by an application which entered an infinite loop, or the crash dialog did not appear at all for some reason. You can try to grab a backtrace with &amp;lt;tt&amp;gt;gdb&amp;lt;/tt&amp;gt;, the [http://sourceware.org/gdb/ GNU Debugger]. GDB is widely available through distribution packages.&lt;br /&gt;
&lt;br /&gt;
Invoking GDB differs from the situation. You can run an application from inside gdb, or attach gdb to an already running process. The latter may be useful when an application already has entered an infinite loop. But we will first start with running an application inside gdb. From the shell, run:&lt;br /&gt;
&lt;br /&gt;
 $ gdb someKDEapp&lt;br /&gt;
&lt;br /&gt;
The GDB prompt will appear. Note that this does not start the application itself, you should run it by invoking the &amp;lt;tt&amp;gt;run&amp;lt;/tt&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
 (gdb) run&lt;br /&gt;
&lt;br /&gt;
This will run the application like you are used to, and you can work with it like normal (it only consumes far more memory and may feel sluggish). Now it's time to reproduce your crash. When you succeed, the application just closes and you should return to your GDB prompt. Now it's time to run the 'backtrace' command:&lt;br /&gt;
&lt;br /&gt;
{{note|Some KDE applications (such as JuK and KTorrent) have special code to ensure that there is only one running instance of the application at a time.  For these applications you should type in &amp;quot;run --nofork&amp;quot; at the (gdb) prompt instead of &amp;quot;run&amp;quot; because otherwise gdb will try to debug the wrong process.  If you are unsure as to whether to use --nofork just try it.  If the application says it's an unknown option you can remove --nofork.}}&lt;br /&gt;
&lt;br /&gt;
 (gdb) thread apply all backtrace&lt;br /&gt;
&lt;br /&gt;
This should give a good backtrace which can be posted at the KDE Bugzilla.&lt;br /&gt;
&lt;br /&gt;
In case you want to attach to an existing process, run the following command in the shell:&lt;br /&gt;
&lt;br /&gt;
 $ gdb someKDEapp pid&lt;br /&gt;
&lt;br /&gt;
where ''pid'' is the process ID of the process you want to attach to. Once attached, and the process is in an infinite loop, after using the 'backtrace' command again a useful backtrace will appear. You can use 'continue' command to let the application run again and press Ctrl+C in gdb to be able to again enter commands.&lt;br /&gt;
&lt;br /&gt;
===Retrieving a backtrace with Valgrind===&lt;br /&gt;
&lt;br /&gt;
When it comes to crashes, [http://www.valgrind.org Valgrind] is also a useful tool to create a backtrace. It's not a substitution for GDB, but rather a supplement.&lt;br /&gt;
&lt;br /&gt;
When you run an application in valgrind, every piece of memory read or written by the application is being checked. Valgrind will report erroneous memory operations in the standard output or in a log file. Since most crashes are due to an invalid memory read, valgrind can be useful to track down where the problem occurs.&lt;br /&gt;
&lt;br /&gt;
{{note|Valgrind consists of several tools in order to check or profile an application. For this article, we only use memcheck, the default tool when valgrind is being invoked.}}&lt;br /&gt;
&lt;br /&gt;
Like GDB, Valgrind makes running an application much slower, while consuming a lot more resources.&lt;br /&gt;
&lt;br /&gt;
Start the application within valgrind:&lt;br /&gt;
&lt;br /&gt;
 $ valgrind --log-file=someKDEapp someKDEapp&lt;br /&gt;
&lt;br /&gt;
Now reproduce the crash. As soon as this happens, the application and valgrind will terminate. What's left is a file named &amp;lt;tt&amp;gt;someKDEapp.pid&amp;lt;/tt&amp;gt; where ''pid'' is replaced by the process ID of the valgrind process. The file may list more errors than the one causing the crash. Here's the bit causing the crash which corresponds to the GDB backtrace above:&lt;br /&gt;
&lt;br /&gt;
 ==23292== Invalid read of size 4&lt;br /&gt;
 ==23292==    at 0x806BD9E: TreeMapItem::parent() const (treemap.h:285)&lt;br /&gt;
 ==23292==    by 0x8065FB9: TreeMapItemList::compareItems(void*, void*) (treemap.cpp:720)&lt;br /&gt;
 ==23292==    by 0x50AC618: QGList::operator==(QGList const&amp;amp;) const (in /usr/qt/3/lib/libqt-mt.so.3.3.8)&lt;br /&gt;
 ==23292==    by 0x806D3BF: QPtrList&amp;lt;TreeMapItem&amp;gt;::operator==(QPtrList&amp;lt;TreeMapItem&amp;gt; const&amp;amp;) const (qptrlist.h:74)&lt;br /&gt;
 ==23292==    by 0x8062DE7: TreeMapWidget::mousePressEvent(QMouseEvent*) (treemap.cpp:1840)&lt;br /&gt;
 ==23292==    by 0x4E2FA62: QWidget::event(QEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)&lt;br /&gt;
 ==23292==    by 0x4D96CA6: QApplication::internalNotify(QObject*, QEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)&lt;br /&gt;
 ==23292==    by 0x4D97A87: QApplication::notify(QObject*, QEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)&lt;br /&gt;
 ==23292==    by 0x4809AC3: KApplication::notify(QObject*, QEvent*) (kapplication.cpp:550)&lt;br /&gt;
 ==23292==    by 0x4D36FD1: QETWidget::translateMouseEvent(_XEvent const*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)&lt;br /&gt;
 ==23292==    by 0x4D368AF: QApplication::x11ProcessEvent(_XEvent*) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)&lt;br /&gt;
 ==23292==    by 0x4D46760: QEventLoop::processEvents(unsigned) (in /usr/qt/3/lib/libqt-mt.so.3.3.8)&lt;br /&gt;
 ==23292==  Address 0x2C is not stack'd, malloc'd or (recently) free'd&lt;br /&gt;
&lt;br /&gt;
But to be sure, just attach the whole log file to the crash report.&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/</id>
		<title>Development/</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/"/>
				<updated>2010-09-11T18:53:43Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: recreated b/c ref at &amp;lt;URL:http://www.kde.org/developerplatform/&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Development]]&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/KDE3/KHTML</id>
		<title>Development/Architecture/KDE3/KHTML</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/KDE3/KHTML"/>
				<updated>2010-05-29T12:55:44Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: technology hyperlinks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== KHTML - KDE's HTML library ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;KHTML&amp;lt;/tt&amp;gt; is an [http://www.w3.org/TR/REC-xml/ XML]/[http://www.w3.org/TR/html401/ HTML4] compliant HTML library, with support for [http://www.w3.org/TR/REC-DOM-Level-1/ DOM],&lt;br /&gt;
[http://java.sun.com/docs/books/tutorial/deployment/applet/index.html Java], [http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf JavaScript] and Cascading Style Sheets ([http://www.w3.org/TR/CSS2/ CSS]). &lt;br /&gt;
&lt;br /&gt;
You can get an overview of &amp;lt;tt&amp;gt;KHTML&amp;lt;/tt&amp;gt;'s current capabilities [http://www.konqueror.org/konq-browser.html here.]&lt;br /&gt;
&lt;br /&gt;
== Small example ==&lt;br /&gt;
&lt;br /&gt;
Using &amp;lt;tt&amp;gt;KHTML&amp;lt;/tt&amp;gt; in your program is quite easy. The following example shows&lt;br /&gt;
you a complete application with which you can already browse the web:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;&lt;br /&gt;
#include &amp;lt;khtml.h&amp;gt;&lt;br /&gt;
#include &amp;lt;kapp.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
    KApplication a(argc, argv, &amp;quot;testkhtml&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    KHTMLWidget *html = new KHTMLWidget;&lt;br /&gt;
    html-&amp;gt;resize(800,500);&lt;br /&gt;
    //html-&amp;gt;setJScriptEnabled(true);&lt;br /&gt;
    html-&amp;gt;setJavaEnabled(true);&lt;br /&gt;
    //html-&amp;gt;setFollowsLinks(false);&lt;br /&gt;
&lt;br /&gt;
    a.setTopWidget(html);&lt;br /&gt;
    html-&amp;gt;setURLCursor(QCursor(PointingHandCursor));&lt;br /&gt;
    html-&amp;gt;openURL(argv[1]);&lt;br /&gt;
&lt;br /&gt;
    QWidget::connect(html, SIGNAL(setTitle(const QString &amp;amp;)),&lt;br /&gt;
                     html, SLOT(setCaption(const QString &amp;amp;)));&lt;br /&gt;
    html-&amp;gt;show();&lt;br /&gt;
    a.exec();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This small example already gives you a functional browser, that lets you browse&lt;br /&gt;
the web (you'll need the &amp;lt;tt&amp;gt;kio_http&amp;lt;/tt&amp;gt; executable from KDE though to access&lt;br /&gt;
non local files). Just try &amp;lt;tt&amp;gt;testkhtml http://www.kde.org&amp;lt;/tt&amp;gt; and you will&lt;br /&gt;
get a widget showing KDE's home page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;KHTML&amp;lt;/tt&amp;gt; has a lot of functionality. Almost everything you'll ever need&lt;br /&gt;
can be accessed through the member functions of the class KHTMLWidget.&lt;br /&gt;
&lt;br /&gt;
== Document Object Model (DOM) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;KHTML&amp;lt;/tt&amp;gt; provides a mostly complete implementation of&lt;br /&gt;
[http://www.w3.org/DOM/ Dom Level 1 and 2].&lt;br /&gt;
&lt;br /&gt;
The DOM is an implementation using internal classes to hold the document's data.&lt;br /&gt;
The classes accessing the DOM are using a refcounting scheme to hold the data.&lt;br /&gt;
Thus the DOM does the memory management for you. You can just use the classes&lt;br /&gt;
defined in the DOM header files to access parts of the document. As long as you&lt;br /&gt;
don't use pointers, you will not get memory leaks.&lt;br /&gt;
&lt;br /&gt;
You can easily access the document being shown by the&lt;br /&gt;
&amp;lt;tt&amp;gt;KHTMLWidget::document()&amp;lt;/tt&amp;gt; method, from where you can&lt;br /&gt;
get access to every part of the document.&lt;br /&gt;
&lt;br /&gt;
== Java ==&lt;br /&gt;
&lt;br /&gt;
Thanks to the work of Richard Moore, &amp;lt;tt&amp;gt;KHTML&amp;lt;/tt&amp;gt; can display Java applets.&lt;br /&gt;
Java is not enabled by default, but you can do so by using&lt;br /&gt;
&amp;lt;tt&amp;gt;KHTMLWidget::setEnableJava(true);&amp;lt;/tt&amp;gt;, and setting the environment variable&lt;br /&gt;
&amp;lt;tt&amp;gt;CLASSPATH&amp;lt;/tt&amp;gt; to:&lt;br /&gt;
&lt;br /&gt;
 CLASSPATH=$KDEDIR/share/apps/kjava/kjava-classes.zip:$JDK_DIR/lib&lt;br /&gt;
&lt;br /&gt;
You will need to have the java developers kit installed though. I tested it&lt;br /&gt;
with JDK-1.1.7, and don't know if it'll run with other versions of JDK or with&lt;br /&gt;
Kaffe.&lt;br /&gt;
&lt;br /&gt;
== JavaScript (ECMA-Script) ==&lt;br /&gt;
&lt;br /&gt;
The JavaScript support aims at compliance with the ECMAScript Language&lt;br /&gt;
specification [http://www.ecma.ch/ecma1/STAND/ECMA-262.HTM ECMA-262] 3rd edition.&lt;br /&gt;
This roughly equals JavaScript 1.5.&lt;br /&gt;
&lt;br /&gt;
== Cascading Style Sheets (CSS) ==&lt;br /&gt;
&lt;br /&gt;
Cascading style sheets 2.1 are mostly supported now.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''Initial Author:'' [mailto:knoll@kde.org Lars Knoll]&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE3]]&lt;br /&gt;
[[Category:Architecture]]&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/KIO_Slaves/Hello_World</id>
		<title>Development/Tutorials/KIO Slaves/Hello World</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/KIO_Slaves/Hello_World"/>
				<updated>2010-05-26T21:58:49Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Test it */ command line access&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Understanding =&lt;br /&gt;
A kioslave allows you to represent any kind of storage in a way you want. As an example, the kio_http kioslave loads data from the network over the http (protocol) and shows it rendered as html. Technically, a kioslave is a shared object plus its description. E.g. the imap4 kioslave consist of the following files:&lt;br /&gt;
 tweedleburg:/usr/local # find -iname &amp;quot;*imap4*&amp;quot;&lt;br /&gt;
 ./lib/kde4/kio_imap4.so&lt;br /&gt;
 ./share/kde4/services/imap4.protocol&lt;br /&gt;
&lt;br /&gt;
= The files =&lt;br /&gt;
We want to write a &amp;quot;hello world&amp;quot; kioslave here. This can be seen as a learning exercise and as a template for future programming projects.&lt;br /&gt;
&lt;br /&gt;
== CMakeLists.txt ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PROJECT( tutorial )&lt;br /&gt;
FIND_PACKAGE(KDE4 REQUIRED)&lt;br /&gt;
INCLUDE_DIRECTORIES( ${KDE4_INCLUDES} . )&lt;br /&gt;
&lt;br /&gt;
set(kio_hello_PART_SRCS&lt;br /&gt;
   hello.cpp)&lt;br /&gt;
&lt;br /&gt;
kde4_add_plugin(kio_hello ${kio_hello_PART_SRCS})&lt;br /&gt;
&lt;br /&gt;
target_link_libraries(kio_hello ${KDE4_KIO_LIBS})&lt;br /&gt;
&lt;br /&gt;
install(TARGETS kio_hello  DESTINATION ${PLUGIN_INSTALL_DIR})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
########### install files ###############&lt;br /&gt;
&lt;br /&gt;
install(FILES hello.protocol DESTINATION ${SERVICES_INSTALL_DIR})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== hello.h ==&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;&lt;br /&gt;
#ifndef HELLO_H&lt;br /&gt;
#define HELLO_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;kio/slavebase.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
  This class implements a hello-world kioslave&lt;br /&gt;
 */&lt;br /&gt;
class hello : public KIO::SlaveBase&lt;br /&gt;
{&lt;br /&gt;
  public:&lt;br /&gt;
    hello( const QByteArray &amp;amp;pool, const QByteArray &amp;amp;app );&lt;br /&gt;
    void get( const KUrl &amp;amp;url );&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== hello.cpp ==&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;&lt;br /&gt;
#include &amp;quot;hello.h&amp;quot;&lt;br /&gt;
#include &amp;lt;kdebug.h&amp;gt; &lt;br /&gt;
#include &amp;lt;kcomponentdata.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot; int KDE_EXPORT kdemain( int argc, char **argv )&lt;br /&gt;
{                                   &lt;br /&gt;
  kDebug(7000) &amp;lt;&amp;lt; &amp;quot;Entering function&amp;quot;;&lt;br /&gt;
  KComponentData instance( &amp;quot;kio_hello&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  if (argc != 4) &lt;br /&gt;
  {&lt;br /&gt;
    fprintf( stderr, &amp;quot;Usage: kio_hello protocol domain-socket1 domain-socket2\n&amp;quot;);&lt;br /&gt;
    exit( -1 );&lt;br /&gt;
  }&lt;br /&gt;
  hello slave( argv[2], argv[3] );&lt;br /&gt;
  slave.dispatchLoop();&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void hello::get( const KUrl &amp;amp;url )&lt;br /&gt;
{&lt;br /&gt;
  kDebug(7000) &amp;lt;&amp;lt; &amp;quot;Entering function&amp;quot;;&lt;br /&gt;
  mimeType( &amp;quot;text/plain&amp;quot; );&lt;br /&gt;
  QByteArray str( &amp;quot;Hello_world&amp;quot; );&lt;br /&gt;
  data( str );&lt;br /&gt;
  finished();&lt;br /&gt;
  kDebug(7000) &amp;lt;&amp;lt; &amp;quot;Leaving function&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
hello::hello( const QByteArray &amp;amp;pool, const QByteArray &amp;amp;app )&lt;br /&gt;
: SlaveBase( &amp;quot;hello&amp;quot;, pool, app ) {}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== hello.protocol == &lt;br /&gt;
 [Protocol]&lt;br /&gt;
 DocPath=kioslave/kio_hello.html &lt;br /&gt;
 exec=kio_hello&lt;br /&gt;
 input=none&lt;br /&gt;
 output=filesystem&lt;br /&gt;
 protocol=hello&lt;br /&gt;
 reading=true&lt;br /&gt;
&lt;br /&gt;
== Compile the stuff ==&lt;br /&gt;
Create a new Folder &amp;quot;build&amp;quot;:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
mkdir build&lt;br /&gt;
cd build&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Run cmake and make&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
cmake ..&lt;br /&gt;
make&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
now you can install it (maybe you should use an experimental setup?)&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
make install&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you should want to do this by hand:&lt;br /&gt;
&lt;br /&gt;
 g++ -shared -lkdeui -lkio -lkdecore -fPIC -I/usr/local/include hello.cpp -o kio_hello.so&lt;br /&gt;
&lt;br /&gt;
''this does not complile if the qt headers are not in /usr/local/include''&lt;br /&gt;
&lt;br /&gt;
''On my system I could fix it by changing -I/usr/local/include to -I/usr/include/qt4''&lt;br /&gt;
== Install the stuff ==&lt;br /&gt;
&lt;br /&gt;
now you can install it (maybe you should use an experimental setup?)&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
make install&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or if you want to install it to your system:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
sudo make install&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course you can also do this by hand&lt;br /&gt;
&lt;br /&gt;
Find out where your protocols are lying:&lt;br /&gt;
 kde4-config --path services&lt;br /&gt;
 /usr/share/kde4/services/&lt;br /&gt;
&lt;br /&gt;
 kde4-config --path module&lt;br /&gt;
 /usr/lib64/kde4/&lt;br /&gt;
&lt;br /&gt;
 cp kio_hello.so /usr/local/lib/kde4/&lt;br /&gt;
 cp kio_hello.so /usr/lib64/kde4/&lt;br /&gt;
 cp kio_hello.protocol /usr/share/kde4/services/&lt;br /&gt;
&lt;br /&gt;
= Test it =&lt;br /&gt;
== in Konqueror ==&lt;br /&gt;
Start kinfocenter, choose hello as protocol. If this is possible, start konqueror, type hello:/// into the URL bar.&lt;br /&gt;
== on the command line ==&lt;br /&gt;
kioclient 'cat' 'hello:///'&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/DCOP</id>
		<title>Development/Architecture/DCOP</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/DCOP"/>
				<updated>2010-05-22T22:17:28Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Performance Tests */ replace entities&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;border: 1px solid #2090ff; padding: 1em 1em 1em 1em; background-color:#f8f8ff; align:center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DCOP: Desktop COmmunications Protocol'''&lt;br /&gt;
&lt;br /&gt;
[mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] October 14, 1999&lt;br /&gt;
&lt;br /&gt;
Revised and extended by [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;] Mar 29, 2000&lt;br /&gt;
&lt;br /&gt;
HTMLized by Hans Meine [mailto:rastajoe@gmx.net Hans Meine &amp;amp;lt;rastajoe@gmx.net&amp;amp;gt;] May 25, 2000&lt;br /&gt;
&lt;br /&gt;
Added a DCOPRef example: Tim Jansen May 12, 2003&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Demotivation and Background ==&lt;br /&gt;
&lt;br /&gt;
'''Note that new features may not be developed for DCOP. The successor for DCOP is D-Bus'''&lt;br /&gt;
&lt;br /&gt;
The motivation behind building a protocol like DCOP is simple.  For&lt;br /&gt;
the past year, we have been attempting to enable interprocess&lt;br /&gt;
communication between KDE applications. KDE already has an extremely&lt;br /&gt;
simple IPC mechanism called KWMcom, which is (was!) used for communicating&lt;br /&gt;
between the panel and the window manager for instance.  It is about as&lt;br /&gt;
simple as it gets, passing messages via X Atoms.  For this reason it&lt;br /&gt;
is limited in the size and complexity of the data that can be passed&lt;br /&gt;
(X atoms must be small to remain efficient) and it also makes it so&lt;br /&gt;
that X is required.  CORBA was thought to be a more effective IPC/RPC&lt;br /&gt;
solution.  However, after a year of attempting to make heavy use of&lt;br /&gt;
CORBA in KDE, we have realized that it is a bit slow and memory&lt;br /&gt;
intensive for simple use.  It also has no authentication available.&lt;br /&gt;
&lt;br /&gt;
What we really needed was an extremely simple protocol with basic&lt;br /&gt;
authorization, along the lines of MIT-MAGIC-COOKIE, as used by X.  It&lt;br /&gt;
would not be able to do NEARLY what CORBA was able to do, but for the&lt;br /&gt;
simple tasks required it would be sufficient. Some examples of such&lt;br /&gt;
tasks might be an application sending a message to the panel saying,&lt;br /&gt;
&amp;quot;I have started, stop displaying the 'application starting' wait&lt;br /&gt;
state,&amp;quot; or having a new application that starts query to see if any&lt;br /&gt;
other applications of the same name are running.  If they are, simply&lt;br /&gt;
call a function on the remote application to create a new window,&lt;br /&gt;
rather than starting a new process.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
DCOP is a simple IPC/RPC mechanism built to operate over sockets.&lt;br /&gt;
Either unix domain sockets or tcp/ip sockets are supported. DCOP is&lt;br /&gt;
built on top of the Inter Client Exchange (ICE) protocol, which comes&lt;br /&gt;
standard as a part of X11R6 and later. It also depends on Qt, but&lt;br /&gt;
beyond that it does not require any other libraries. Because of this,&lt;br /&gt;
it is extremely lightweight, enabling it to be linked into all KDE&lt;br /&gt;
applications with low overhead.&lt;br /&gt;
&lt;br /&gt;
=== Model ===&lt;br /&gt;
&lt;br /&gt;
The model is simple.  Each application using DCOP is a client.  They&lt;br /&gt;
communicate to each other through a DCOP server, which functions like&lt;br /&gt;
a traffic director, dispatching messages/calls to the proper&lt;br /&gt;
destinations.  All clients are peers of each other.&lt;br /&gt;
&lt;br /&gt;
Two types of actions are possible with DCOP: &amp;quot;send and forget&amp;quot;&lt;br /&gt;
messages, which do not block, and &amp;quot;calls,&amp;quot; which block waiting for&lt;br /&gt;
some data to be returned.&lt;br /&gt;
&lt;br /&gt;
Any data that will be sent is serialized (marshalled, for you CORBA&lt;br /&gt;
fellows) using the built-in {{qt3|QDataStream}} operators available in all of&lt;br /&gt;
the Qt classes.  This is fast and easy.  In fact it's so little work&lt;br /&gt;
that you can easily write the marshalling code by hand. In addition,&lt;br /&gt;
there's a simple IDL-like compiler available (dcopidl and dcopidl2cpp)&lt;br /&gt;
that generates stubs and skeletons for you. Using the dcopidl compiler&lt;br /&gt;
has the additional benefit of type safety.&lt;br /&gt;
&lt;br /&gt;
This HOWTO describes the manual method first and covers the dcopidl&lt;br /&gt;
compiler later.&lt;br /&gt;
&lt;br /&gt;
=== Managing DCOP Connections Manually ===&lt;br /&gt;
&lt;br /&gt;
==== Establishing the Connection ====&lt;br /&gt;
&lt;br /&gt;
{{class|KApplication|kdelibs|3.5}} has gained a method called &amp;quot;KApplication::dcopClient()&amp;quot;&lt;br /&gt;
which returns a pointer to a DCOPClient instance.  The first time this&lt;br /&gt;
method is called, the client class will be created.  {{class|DCOPClient|kdelibs|3.5}}s have&lt;br /&gt;
unique identifiers attached to them which are based on what&lt;br /&gt;
KApplication::name() returns.  In fact, if there is only a single&lt;br /&gt;
instance of the program running, the appId will be equal to&lt;br /&gt;
KApplication::name().&lt;br /&gt;
&lt;br /&gt;
To actually enable DCOP communication to begin, you must use&lt;br /&gt;
DCOPClient::attach().  This will attempt to attach to the DCOP server.&lt;br /&gt;
If no server is found or there is any other type of error, attach()&lt;br /&gt;
will return false. KApplication will catch a dcop signal and display an&lt;br /&gt;
appropriate error message box in that case.&lt;br /&gt;
&lt;br /&gt;
After connecting with the server via DCOPClient::attach(), you need to&lt;br /&gt;
register this appId with the server so it knows about you.  Otherwise,&lt;br /&gt;
you are communicating anonymously.  Use the&lt;br /&gt;
DCOPClient::registerAs(const QCString &amp;amp;amp;name) to do so.  In the simple&lt;br /&gt;
case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * returns the appId that is actually registered, which _may_ be&lt;br /&gt;
 * different from what you passed&lt;br /&gt;
 */&lt;br /&gt;
appId = client -&amp;gt; registerAs (kApp -&amp;gt; name());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you never retrieve the DCOPClient pointer from KApplication, the&lt;br /&gt;
object will not be created and thus there will be no memory overhead.&lt;br /&gt;
&lt;br /&gt;
You may also detach from the server by calling DCOPClient::detach().&lt;br /&gt;
If you wish to attach again you will need to re-register as well.  If&lt;br /&gt;
you only wish to change the ID under which you are registered, simply&lt;br /&gt;
call DCOPClient::registerAs() with the new name.&lt;br /&gt;
&lt;br /&gt;
KUniqueApplication automatically registers itself to DCOP. If you&lt;br /&gt;
are using KUniqueApplication you should not attach or register&lt;br /&gt;
yourself, this is already done. The appId is by definition&lt;br /&gt;
equal to kapp-&amp;amp;gt;name(). You can retrieve the registered DCOP client&lt;br /&gt;
by calling kapp-&amp;amp;gt;dcopClient().&lt;br /&gt;
&lt;br /&gt;
==== Sending Data to a Remote Application ====&lt;br /&gt;
&lt;br /&gt;
To actually communicate, you have one of two choices.  You may either&lt;br /&gt;
call the &amp;quot;send&amp;quot; or the &amp;quot;call&amp;quot; method.  Both methods require three&lt;br /&gt;
identification parameters: an application identifier, a remote object,&lt;br /&gt;
a remote function. Sending is asynchronous (i.e. it returns immediately)&lt;br /&gt;
and may or may not result in your own application being sent a message at&lt;br /&gt;
some point in the future. Then &amp;quot;send&amp;quot; requires one and &amp;quot;call&amp;quot; requires&lt;br /&gt;
two data parameters.&lt;br /&gt;
&lt;br /&gt;
The remote object must be specified as an object hierarchy.  That is,&lt;br /&gt;
if the toplevel object is called &amp;quot;fooObject&amp;quot; and has the child&lt;br /&gt;
&amp;quot;barObject&amp;quot;, you would reference this object as &amp;quot;fooObject/barObject&amp;quot;.&lt;br /&gt;
Functions must be described by a full function signature.  If the&lt;br /&gt;
remote function is called &amp;quot;doIt&amp;quot;, and it takes an int, it would be&lt;br /&gt;
described as &amp;quot;doIt(int)&amp;quot;.  Please note that the return type is not&lt;br /&gt;
specified here, as it is not part of the function signature (or at&lt;br /&gt;
least the C++ understanding of a function signature).  You will get&lt;br /&gt;
the return type of a function back as an extra parameter to&lt;br /&gt;
DCOPClient::call().  See the section on call() for more details.&lt;br /&gt;
&lt;br /&gt;
In order to actually get the data to the remote client, it must be&lt;br /&gt;
&amp;quot;serialized&amp;quot; via a {{qt3|QDataStream}} operating on a {{qt3|QByteArray}}. This is how&lt;br /&gt;
the data parameter is &amp;quot;built&amp;quot;. A few examples will make clear how this&lt;br /&gt;
works.&lt;br /&gt;
&lt;br /&gt;
Say you want to call &amp;quot;doIt&amp;quot; as described above, and not block (or wait&lt;br /&gt;
for a response).  You will not receive the return value of the remotely&lt;br /&gt;
called function, but you will not hang while the RPC is processed either.&lt;br /&gt;
The return value of send() indicates whether DCOP communication succeeded&lt;br /&gt;
or not.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data;&lt;br /&gt;
QDataStream arg(data, IO_WriteOnly);&lt;br /&gt;
arg &amp;lt;&amp;lt; 5;&lt;br /&gt;
if (!client -&amp;gt; send (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data))&lt;br /&gt;
    qDebug (&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OK, now let's say we wanted to get the data back from the remotely&lt;br /&gt;
called function.  You have to execute a call() instead of a send().&lt;br /&gt;
The returned value will then be available in the data parameter &amp;quot;reply&amp;quot;.&lt;br /&gt;
The actual return value of call() is still whether or not DCOP&lt;br /&gt;
communication was successful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data, replyData;&lt;br /&gt;
QCString replyType;&lt;br /&gt;
QDataStream arg (data, IO_WriteOnly);&lt;br /&gt;
arg &amp;lt;&amp;lt; 5;&lt;br /&gt;
if (!client -&amp;gt; call (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data, replyType, replyData))&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    QDataStream reply (replyData, IO_ReadOnly);&lt;br /&gt;
    if (replyType == &amp;quot;QString&amp;quot;) {&lt;br /&gt;
        QString result;&lt;br /&gt;
        reply &amp;gt;&amp;gt; result;&lt;br /&gt;
        print (&amp;quot;the result is: %s&amp;quot;, result. latin1());&lt;br /&gt;
    } else&lt;br /&gt;
        qDebug (&amp;quot;doIt returned an unexpected type of reply!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''N.B.:'' You cannot call() a method belonging to an application which has&lt;br /&gt;
registered with an unique numeric id appended to its textual name (see&lt;br /&gt;
dcopclient.h for more info). In this case, DCOP would not know which&lt;br /&gt;
application it should connect with to call the method. This is not an issue&lt;br /&gt;
with send(), as you can broadcast to all applications that have registered&lt;br /&gt;
with appname-&amp;amp;lt;numeric_id&amp;amp;gt; by using a wildcard (e.g. 'konsole-*'), which&lt;br /&gt;
will send your signal to all applications called 'konsole'.&lt;br /&gt;
&lt;br /&gt;
Since KDE 3.1 there is an even easier way to make a DCOP call:&lt;br /&gt;
{{class|DCOPRef|kdelibs|3.5}}. Then you only need to create a DCOPRef to the object&lt;br /&gt;
and as long as the function does not use unusual argument types,&lt;br /&gt;
calling the function is as easy as this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
DCOPRef barObject (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;);&lt;br /&gt;
DCOPReply reply = barObject. call (&amp;quot;doIt&amp;quot;, 5);&lt;br /&gt;
if (!reply. isValid())&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    print(&amp;quot;the result is: %s&amp;quot;, ((QString)reply). latin1());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Receiving Data via DCOP ====&lt;br /&gt;
&lt;br /&gt;
Currently the only real way to receive data from DCOP is to multiply&lt;br /&gt;
inherit from the normal class that you are inheriting (usually some&lt;br /&gt;
sort of QWidget subclass or QObject) as well as the DCOPObject class.&lt;br /&gt;
DCOPObject provides one very important method: DCOPObject::process().&lt;br /&gt;
This is a pure virtual method that you must implement in order to&lt;br /&gt;
process DCOP messages that you receive.  It takes a function&lt;br /&gt;
signature, QByteArray of parameters, and a reference to a QByteArray&lt;br /&gt;
for the reply data that you must fill in.&lt;br /&gt;
&lt;br /&gt;
Think of DCOPObject::process() as a sort of dispatch agent.  In the&lt;br /&gt;
future, there will probably be a precompiler for your sources to write&lt;br /&gt;
this method for you.  However, until that point you need to examine&lt;br /&gt;
the incoming function signature and take action accordingly.  Here is&lt;br /&gt;
an example implementation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject:: process (const QCString &amp;amp;fun, const QByteArray &amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;replyType, QByteArray &amp;amp;replyData)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg (data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;gt;&amp;gt; i;&lt;br /&gt;
        QString result = self -&amp;gt; doIt (i);&lt;br /&gt;
        QDataStream reply (replyData, IO_WriteOnly);&lt;br /&gt;
        reply &amp;lt;&amp;lt; result;&lt;br /&gt;
        replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug (&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Processing Received Calls with Transactions ====&lt;br /&gt;
&lt;br /&gt;
If your applications is able to process incoming function calls&lt;br /&gt;
right away the above code is all you need. When your application&lt;br /&gt;
needs to do more complex tasks you might want to do the processing&lt;br /&gt;
out of 'process' function call and send the result back later when&lt;br /&gt;
it becomes available.&lt;br /&gt;
&lt;br /&gt;
For this you can ask your DCOPClient for a transactionId. You can&lt;br /&gt;
then return from the 'process' function and when the result is&lt;br /&gt;
available finish the transaction. In the mean time your application&lt;br /&gt;
can receive incoming DCOP function calls from other clients.&lt;br /&gt;
&lt;br /&gt;
Such code could like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject::process(const QCString &amp;amp;fun, const QByteArray &amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;, QByteArray &amp;amp;)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg (data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;gt;&amp;gt; i;&lt;br /&gt;
        QString result = self -&amp;gt; doIt(i);&lt;br /&gt;
&lt;br /&gt;
        DCOPClientTransaction *myTransaction;&lt;br /&gt;
        myTransaction = kapp -&amp;gt; dcopClient() -&amp;gt; beginTransaction();&lt;br /&gt;
&lt;br /&gt;
        // start processing...&lt;br /&gt;
        // Calls slotProcessingDone when finished.&lt;br /&gt;
        startProcessing (myTransaction, i);&lt;br /&gt;
&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug(&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
slotProcessingDone(DCOPClientTransaction *myTransaction, const QString &amp;amp;result)&lt;br /&gt;
{&lt;br /&gt;
    QCString replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
    QByteArray replyData;&lt;br /&gt;
    QDataStream reply(replyData, IO_WriteOnly);&lt;br /&gt;
    reply &amp;lt;&amp;lt; result;&lt;br /&gt;
    kapp &lt;br /&gt;
-&amp;gt; dcopClient() -&amp;gt; endTransaction(myTransaction, replyType, replyData);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DCOP Signals ====&lt;br /&gt;
&lt;br /&gt;
Sometimes a component wants to send notifications via DCOP to other&lt;br /&gt;
components but does not know which components will be interested in these&lt;br /&gt;
notifications. One could use a broadcast in such a case but this is a very&lt;br /&gt;
crude method. For a more sophisticated method DCOP signals have been invented.&lt;br /&gt;
&lt;br /&gt;
DCOP signals are very similair to Qt signals, there are some differences &lt;br /&gt;
though. A DCOP signal can be connected to a DCOP function. Whenever the DCOP&lt;br /&gt;
signal gets emitted, the DCOP functions to which the signal is connected are&lt;br /&gt;
being called. DCOP signals are, just like Qt signals, one way. They do not&lt;br /&gt;
provide a return value. &lt;br /&gt;
&lt;br /&gt;
A DCOP signal originates from a DCOP Object/DCOP Client combination (sender). &lt;br /&gt;
It can be connected to a function of another DCOP Object/DCOP Client &lt;br /&gt;
combination (receiver).&lt;br /&gt;
&lt;br /&gt;
There are two major differences between connections of Qt signals and&lt;br /&gt;
connections of DCOP signals. In DCOP, unlike Qt, a signal connections can&lt;br /&gt;
have an anonymous sender and, unlike Qt, a DCOP signal connection can be&lt;br /&gt;
non-volatile.&lt;br /&gt;
&lt;br /&gt;
With DCOP one can connect a signal without specifying the sending DCOP Object &lt;br /&gt;
or DCOP Client. In that case signals from any DCOP Object and/or DCOP Client&lt;br /&gt;
will be delivered. This allows the specification of certain events without&lt;br /&gt;
tying oneself to a certain object that implementes the events.&lt;br /&gt;
&lt;br /&gt;
Another DCOP feature are so called non-volatile connections. With Qt signal&lt;br /&gt;
connections, the connection gets deleted when either sender or receiver of&lt;br /&gt;
the signal gets deleted. A volatile DCOP signal connection will behave the&lt;br /&gt;
same. However, a non-volatile DCOP signal connection will not get deleted &lt;br /&gt;
when the sending object gets deleted. Once a new object gets created with &lt;br /&gt;
the same name as the original sending object, the connection will be restored.&lt;br /&gt;
There is no difference between the two when the receiving object gets deleted,&lt;br /&gt;
in that case the signal connection will always be deleted.&lt;br /&gt;
&lt;br /&gt;
A receiver can create a non-volatile connection while the sender doesn't (yet)&lt;br /&gt;
exist. An anonymous DCOP connection should always be non-volatile.&lt;br /&gt;
&lt;br /&gt;
The following example shows how KLauncher emits a signal whenever it notices&lt;br /&gt;
that an application that was started via KLauncher terminates.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray params;&lt;br /&gt;
QDataStream stream (params, IO_WriteOnly);&lt;br /&gt;
stream &amp;lt;&amp;lt; pid;&lt;br /&gt;
kapp -&amp;gt; dcopClient() -&amp;gt; emitDCOPSignal (&amp;quot;clientDied(pid_t)&amp;quot;, params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The task manager of the KDE panel connects to this signal. It uses an &lt;br /&gt;
anonymous connection (it doesn't require that the signal is being emitted&lt;br /&gt;
by KLauncher) that is non-volatile:&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
connectDCOPSignal (0, 0, &amp;quot;clientDied(pid_t)&amp;quot;, &amp;quot;clientDied(pid_t)&amp;quot;, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It connects the clientDied(pid_t) signal to its own clientDied(pid_t) DCOP&lt;br /&gt;
function. In this case the signal and the function to call have the same name.&lt;br /&gt;
This isn't needed as long as the arguments of both signal and receiving function&lt;br /&gt;
match. The receiving function may ignore one or more of the trailing arguments&lt;br /&gt;
of the signal. E.g. it is allowed to connect the clientDied(pid_t) signal to&lt;br /&gt;
a clientDied(void) DCOP function.&lt;br /&gt;
&lt;br /&gt;
=== Using the dcopidl compiler ===&lt;br /&gt;
&lt;br /&gt;
dcopidl makes setting up a DCOP server easy. Instead of having to implement&lt;br /&gt;
the process() method and unmarshalling (retrieving from QByteArray) parameters&lt;br /&gt;
manually, you can let dcopidl create the necessary code on your behalf.&lt;br /&gt;
&lt;br /&gt;
This also allows you to describe the interface for your class in a&lt;br /&gt;
single, separate header file.&lt;br /&gt;
&lt;br /&gt;
Writing an IDL file is very similar to writing a normal C++ header. An&lt;br /&gt;
exception is the keyword 'ASYNC'. It indicates that a call to this&lt;br /&gt;
function shall be processed asynchronously. For the C++ compiler, it&lt;br /&gt;
expands to 'void'.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#ifndef MY_INTERFACE_H&lt;br /&gt;
#define MY_INTERFACE_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;dcopobject.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class MyInterface : virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
&lt;br /&gt;
        virtual ASYNC myAsynchronousMethod (QString someParameter) = 0;&lt;br /&gt;
        virtual QRect mySynchronousMethod() = 0;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, you're essentially declaring an abstract base class, which&lt;br /&gt;
virtually inherits from DCOPObject.&lt;br /&gt;
&lt;br /&gt;
If you're using the standard KDE build scripts, then you can simply add this file (which you would call {{path|MyInterface.h}}) to your sources directory. Then you edit your {{path|Makefile.am}}, adding 'MyInterface.skel' to your SOURCES list and {{path|MyInterface.h}} to include_HEADERS.&lt;br /&gt;
&lt;br /&gt;
The build scripts will use dcopidl to parse {{path|MyInterface.h}}, converting it to an XML description in {{path|MyInterface.kidl}}. Next, a file called {{path|MyInterface_skel.cpp}} will automatically be created, compiled and linked with your binary.&lt;br /&gt;
&lt;br /&gt;
The next thing you have to do is to choose which of your classes will implement the interface described in {{path|MyInterface.h}}. Alter the inheritance of this class such that it virtually inherits from {{path|MyInterface}}. Then add declarations to your class interface similar to those on {{path|MyInterface.h}}, but virtual, not pure virtual.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public MyInterface&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: (Qt issue) Remember that if you are inheriting from {{qt3|QObject}}, you must place it first in the list of inherited classes.&lt;br /&gt;
&lt;br /&gt;
In the implementation of your class' ctor, you must explicitly initialize&lt;br /&gt;
those classes from which you are inheriting from. This is, of course, good&lt;br /&gt;
practise, but it is essential here as you need to tell DCOPObject the name of&lt;br /&gt;
the interface which your are implementing.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
MyClass::MyClass()&lt;br /&gt;
  : QObject(),&lt;br /&gt;
    DCOPObject(&amp;quot;MyInterface&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
    // whatever...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can simply implement the methods you have declared in your interface,&lt;br /&gt;
exactly the same as you would normally.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
void MyClass::myAsynchronousMethod(QString someParameter)&lt;br /&gt;
{&lt;br /&gt;
    qDebug(&amp;quot;myAsyncMethod called with param `&amp;quot; + someParameter + &amp;quot;'&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is not necessary (though very clean) to define an interface as an&lt;br /&gt;
abstract class of its own, like we did in the example above. We could&lt;br /&gt;
just as well have defined a k_dcop section directly within MyClass:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to skeletons, dcopidl2cpp also generate stubs. Those make&lt;br /&gt;
it easy to call a DCOP interface without doing the marshalling&lt;br /&gt;
manually. To use a stub, add {{path|MyInterface.stub}} to the SOURCES list of&lt;br /&gt;
your {{path|Makefile.am}}. The stub class will then be called MyInterface_stub.&lt;br /&gt;
&lt;br /&gt;
=== Inter-user communication ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it might be interesting to use DCOP between processes&lt;br /&gt;
belonging to different users, e.g. a frontend process running&lt;br /&gt;
with the user's id, and a backend process running as root.&lt;br /&gt;
&lt;br /&gt;
To do this, two steps have to be taken:&lt;br /&gt;
* both processes need to talk to the same DCOP server&lt;br /&gt;
* proper authentication must be ensured&lt;br /&gt;
&lt;br /&gt;
For the first step, you simply pass the server address (as&lt;br /&gt;
found in .DCOPserver) to the second process. For the authentication,&lt;br /&gt;
you can use the ICEAUTHORITY environment variable to tell the&lt;br /&gt;
second process where to find the authentication information.&lt;br /&gt;
(Note that this implies that the second process is able to&lt;br /&gt;
read the authentication file, so it will probably only work&lt;br /&gt;
if the second process runs as root. If it should run as another&lt;br /&gt;
user, a similar approach to what kdesu does with xauth must&lt;br /&gt;
be taken. In fact, it would be a very good idea to add DCOP&lt;br /&gt;
support to kdesu!)&lt;br /&gt;
&lt;br /&gt;
For example&lt;br /&gt;
 ICEAUTHORITY=~user/.ICEauthority kdesu root -c kcmroot -dcopserver `cat ~user/.DCOPserver`&lt;br /&gt;
&lt;br /&gt;
will, after kdesu got the root password, execute kcmroot as root, talking&lt;br /&gt;
to the user's dcop server.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' DCOP communication is not encrypted, so please do not&lt;br /&gt;
pass important information around this way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Performance Tests ==&lt;br /&gt;
&lt;br /&gt;
A few back-of-the-napkin tests folks:&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#include &amp;lt;kapp.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    KApplication *app;&lt;br /&gt;
&lt;br /&gt;
    app = new KApplication (argc, argv, &amp;quot;testit&amp;quot;);&lt;br /&gt;
    return app -&amp;gt; exec();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compiled with:&lt;br /&gt;
 g++ -O2 -o testit testit.cpp -I$QTDIR/include -L$QTDIR/lib -lkdecore&lt;br /&gt;
&lt;br /&gt;
on Linux yields the following memory use statistics:&lt;br /&gt;
 VmSize:     8076 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4532 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
If I create the KApplication's DCOPClient, and call attach() and&lt;br /&gt;
registerAs(), it changes to this:&lt;br /&gt;
 VmSize:     8080 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4624 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
Basically it appears that using DCOP causes 100k more memory to be&lt;br /&gt;
resident, but no more data or stack.  So this will be shared between all&lt;br /&gt;
processes, right?  100k to enable DCOP in all apps doesn't seem bad at&lt;br /&gt;
all. :)&lt;br /&gt;
&lt;br /&gt;
OK now for some timings.  Just creating a KApplication and then exiting&lt;br /&gt;
(i.e. removing the call to KApplication::exec) takes this much time:&lt;br /&gt;
&lt;br /&gt;
 0.28user 0.02system 0:00.32elapsed 92%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1084major+62minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second on my PII-233.  Now, if we create our DCOP&lt;br /&gt;
object and attach to the server, it takes this long:&lt;br /&gt;
&lt;br /&gt;
 0.27user 0.03system 0:00.34elapsed 87%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1107major+65minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second.  Basically DCOPClient creation and attaching&lt;br /&gt;
gets lost in the statistical variation (&amp;quot;noise&amp;quot;).  I was getting times&lt;br /&gt;
between .32 and .48 over several runs for both of the example programs, so&lt;br /&gt;
obviously system load is more relevant than the extra two calls to&lt;br /&gt;
DCOPClient::attach and DCOPClient::registerAs, as well as the actual&lt;br /&gt;
DCOPClient constructor time.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Hopefully this document will get you well on your way into the world&lt;br /&gt;
of inter-process communication with KDE! Please direct all comments&lt;br /&gt;
and/or suggestions to [mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] and [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;].&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE3]]&lt;br /&gt;
[[Category:Architecture]]&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/DCOP</id>
		<title>Development/Architecture/DCOP</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/DCOP"/>
				<updated>2010-05-22T22:15:42Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Using the dcopidl compiler */ replace entities&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;border: 1px solid #2090ff; padding: 1em 1em 1em 1em; background-color:#f8f8ff; align:center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DCOP: Desktop COmmunications Protocol'''&lt;br /&gt;
&lt;br /&gt;
[mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] October 14, 1999&lt;br /&gt;
&lt;br /&gt;
Revised and extended by [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;] Mar 29, 2000&lt;br /&gt;
&lt;br /&gt;
HTMLized by Hans Meine [mailto:rastajoe@gmx.net Hans Meine &amp;amp;lt;rastajoe@gmx.net&amp;amp;gt;] May 25, 2000&lt;br /&gt;
&lt;br /&gt;
Added a DCOPRef example: Tim Jansen May 12, 2003&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Demotivation and Background ==&lt;br /&gt;
&lt;br /&gt;
'''Note that new features may not be developed for DCOP. The successor for DCOP is D-Bus'''&lt;br /&gt;
&lt;br /&gt;
The motivation behind building a protocol like DCOP is simple.  For&lt;br /&gt;
the past year, we have been attempting to enable interprocess&lt;br /&gt;
communication between KDE applications. KDE already has an extremely&lt;br /&gt;
simple IPC mechanism called KWMcom, which is (was!) used for communicating&lt;br /&gt;
between the panel and the window manager for instance.  It is about as&lt;br /&gt;
simple as it gets, passing messages via X Atoms.  For this reason it&lt;br /&gt;
is limited in the size and complexity of the data that can be passed&lt;br /&gt;
(X atoms must be small to remain efficient) and it also makes it so&lt;br /&gt;
that X is required.  CORBA was thought to be a more effective IPC/RPC&lt;br /&gt;
solution.  However, after a year of attempting to make heavy use of&lt;br /&gt;
CORBA in KDE, we have realized that it is a bit slow and memory&lt;br /&gt;
intensive for simple use.  It also has no authentication available.&lt;br /&gt;
&lt;br /&gt;
What we really needed was an extremely simple protocol with basic&lt;br /&gt;
authorization, along the lines of MIT-MAGIC-COOKIE, as used by X.  It&lt;br /&gt;
would not be able to do NEARLY what CORBA was able to do, but for the&lt;br /&gt;
simple tasks required it would be sufficient. Some examples of such&lt;br /&gt;
tasks might be an application sending a message to the panel saying,&lt;br /&gt;
&amp;quot;I have started, stop displaying the 'application starting' wait&lt;br /&gt;
state,&amp;quot; or having a new application that starts query to see if any&lt;br /&gt;
other applications of the same name are running.  If they are, simply&lt;br /&gt;
call a function on the remote application to create a new window,&lt;br /&gt;
rather than starting a new process.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
DCOP is a simple IPC/RPC mechanism built to operate over sockets.&lt;br /&gt;
Either unix domain sockets or tcp/ip sockets are supported. DCOP is&lt;br /&gt;
built on top of the Inter Client Exchange (ICE) protocol, which comes&lt;br /&gt;
standard as a part of X11R6 and later. It also depends on Qt, but&lt;br /&gt;
beyond that it does not require any other libraries. Because of this,&lt;br /&gt;
it is extremely lightweight, enabling it to be linked into all KDE&lt;br /&gt;
applications with low overhead.&lt;br /&gt;
&lt;br /&gt;
=== Model ===&lt;br /&gt;
&lt;br /&gt;
The model is simple.  Each application using DCOP is a client.  They&lt;br /&gt;
communicate to each other through a DCOP server, which functions like&lt;br /&gt;
a traffic director, dispatching messages/calls to the proper&lt;br /&gt;
destinations.  All clients are peers of each other.&lt;br /&gt;
&lt;br /&gt;
Two types of actions are possible with DCOP: &amp;quot;send and forget&amp;quot;&lt;br /&gt;
messages, which do not block, and &amp;quot;calls,&amp;quot; which block waiting for&lt;br /&gt;
some data to be returned.&lt;br /&gt;
&lt;br /&gt;
Any data that will be sent is serialized (marshalled, for you CORBA&lt;br /&gt;
fellows) using the built-in {{qt3|QDataStream}} operators available in all of&lt;br /&gt;
the Qt classes.  This is fast and easy.  In fact it's so little work&lt;br /&gt;
that you can easily write the marshalling code by hand. In addition,&lt;br /&gt;
there's a simple IDL-like compiler available (dcopidl and dcopidl2cpp)&lt;br /&gt;
that generates stubs and skeletons for you. Using the dcopidl compiler&lt;br /&gt;
has the additional benefit of type safety.&lt;br /&gt;
&lt;br /&gt;
This HOWTO describes the manual method first and covers the dcopidl&lt;br /&gt;
compiler later.&lt;br /&gt;
&lt;br /&gt;
=== Managing DCOP Connections Manually ===&lt;br /&gt;
&lt;br /&gt;
==== Establishing the Connection ====&lt;br /&gt;
&lt;br /&gt;
{{class|KApplication|kdelibs|3.5}} has gained a method called &amp;quot;KApplication::dcopClient()&amp;quot;&lt;br /&gt;
which returns a pointer to a DCOPClient instance.  The first time this&lt;br /&gt;
method is called, the client class will be created.  {{class|DCOPClient|kdelibs|3.5}}s have&lt;br /&gt;
unique identifiers attached to them which are based on what&lt;br /&gt;
KApplication::name() returns.  In fact, if there is only a single&lt;br /&gt;
instance of the program running, the appId will be equal to&lt;br /&gt;
KApplication::name().&lt;br /&gt;
&lt;br /&gt;
To actually enable DCOP communication to begin, you must use&lt;br /&gt;
DCOPClient::attach().  This will attempt to attach to the DCOP server.&lt;br /&gt;
If no server is found or there is any other type of error, attach()&lt;br /&gt;
will return false. KApplication will catch a dcop signal and display an&lt;br /&gt;
appropriate error message box in that case.&lt;br /&gt;
&lt;br /&gt;
After connecting with the server via DCOPClient::attach(), you need to&lt;br /&gt;
register this appId with the server so it knows about you.  Otherwise,&lt;br /&gt;
you are communicating anonymously.  Use the&lt;br /&gt;
DCOPClient::registerAs(const QCString &amp;amp;amp;name) to do so.  In the simple&lt;br /&gt;
case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * returns the appId that is actually registered, which _may_ be&lt;br /&gt;
 * different from what you passed&lt;br /&gt;
 */&lt;br /&gt;
appId = client -&amp;gt; registerAs (kApp -&amp;gt; name());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you never retrieve the DCOPClient pointer from KApplication, the&lt;br /&gt;
object will not be created and thus there will be no memory overhead.&lt;br /&gt;
&lt;br /&gt;
You may also detach from the server by calling DCOPClient::detach().&lt;br /&gt;
If you wish to attach again you will need to re-register as well.  If&lt;br /&gt;
you only wish to change the ID under which you are registered, simply&lt;br /&gt;
call DCOPClient::registerAs() with the new name.&lt;br /&gt;
&lt;br /&gt;
KUniqueApplication automatically registers itself to DCOP. If you&lt;br /&gt;
are using KUniqueApplication you should not attach or register&lt;br /&gt;
yourself, this is already done. The appId is by definition&lt;br /&gt;
equal to kapp-&amp;amp;gt;name(). You can retrieve the registered DCOP client&lt;br /&gt;
by calling kapp-&amp;amp;gt;dcopClient().&lt;br /&gt;
&lt;br /&gt;
==== Sending Data to a Remote Application ====&lt;br /&gt;
&lt;br /&gt;
To actually communicate, you have one of two choices.  You may either&lt;br /&gt;
call the &amp;quot;send&amp;quot; or the &amp;quot;call&amp;quot; method.  Both methods require three&lt;br /&gt;
identification parameters: an application identifier, a remote object,&lt;br /&gt;
a remote function. Sending is asynchronous (i.e. it returns immediately)&lt;br /&gt;
and may or may not result in your own application being sent a message at&lt;br /&gt;
some point in the future. Then &amp;quot;send&amp;quot; requires one and &amp;quot;call&amp;quot; requires&lt;br /&gt;
two data parameters.&lt;br /&gt;
&lt;br /&gt;
The remote object must be specified as an object hierarchy.  That is,&lt;br /&gt;
if the toplevel object is called &amp;quot;fooObject&amp;quot; and has the child&lt;br /&gt;
&amp;quot;barObject&amp;quot;, you would reference this object as &amp;quot;fooObject/barObject&amp;quot;.&lt;br /&gt;
Functions must be described by a full function signature.  If the&lt;br /&gt;
remote function is called &amp;quot;doIt&amp;quot;, and it takes an int, it would be&lt;br /&gt;
described as &amp;quot;doIt(int)&amp;quot;.  Please note that the return type is not&lt;br /&gt;
specified here, as it is not part of the function signature (or at&lt;br /&gt;
least the C++ understanding of a function signature).  You will get&lt;br /&gt;
the return type of a function back as an extra parameter to&lt;br /&gt;
DCOPClient::call().  See the section on call() for more details.&lt;br /&gt;
&lt;br /&gt;
In order to actually get the data to the remote client, it must be&lt;br /&gt;
&amp;quot;serialized&amp;quot; via a {{qt3|QDataStream}} operating on a {{qt3|QByteArray}}. This is how&lt;br /&gt;
the data parameter is &amp;quot;built&amp;quot;. A few examples will make clear how this&lt;br /&gt;
works.&lt;br /&gt;
&lt;br /&gt;
Say you want to call &amp;quot;doIt&amp;quot; as described above, and not block (or wait&lt;br /&gt;
for a response).  You will not receive the return value of the remotely&lt;br /&gt;
called function, but you will not hang while the RPC is processed either.&lt;br /&gt;
The return value of send() indicates whether DCOP communication succeeded&lt;br /&gt;
or not.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data;&lt;br /&gt;
QDataStream arg(data, IO_WriteOnly);&lt;br /&gt;
arg &amp;lt;&amp;lt; 5;&lt;br /&gt;
if (!client -&amp;gt; send (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data))&lt;br /&gt;
    qDebug (&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OK, now let's say we wanted to get the data back from the remotely&lt;br /&gt;
called function.  You have to execute a call() instead of a send().&lt;br /&gt;
The returned value will then be available in the data parameter &amp;quot;reply&amp;quot;.&lt;br /&gt;
The actual return value of call() is still whether or not DCOP&lt;br /&gt;
communication was successful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data, replyData;&lt;br /&gt;
QCString replyType;&lt;br /&gt;
QDataStream arg (data, IO_WriteOnly);&lt;br /&gt;
arg &amp;lt;&amp;lt; 5;&lt;br /&gt;
if (!client -&amp;gt; call (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data, replyType, replyData))&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    QDataStream reply (replyData, IO_ReadOnly);&lt;br /&gt;
    if (replyType == &amp;quot;QString&amp;quot;) {&lt;br /&gt;
        QString result;&lt;br /&gt;
        reply &amp;gt;&amp;gt; result;&lt;br /&gt;
        print (&amp;quot;the result is: %s&amp;quot;, result. latin1());&lt;br /&gt;
    } else&lt;br /&gt;
        qDebug (&amp;quot;doIt returned an unexpected type of reply!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''N.B.:'' You cannot call() a method belonging to an application which has&lt;br /&gt;
registered with an unique numeric id appended to its textual name (see&lt;br /&gt;
dcopclient.h for more info). In this case, DCOP would not know which&lt;br /&gt;
application it should connect with to call the method. This is not an issue&lt;br /&gt;
with send(), as you can broadcast to all applications that have registered&lt;br /&gt;
with appname-&amp;amp;lt;numeric_id&amp;amp;gt; by using a wildcard (e.g. 'konsole-*'), which&lt;br /&gt;
will send your signal to all applications called 'konsole'.&lt;br /&gt;
&lt;br /&gt;
Since KDE 3.1 there is an even easier way to make a DCOP call:&lt;br /&gt;
{{class|DCOPRef|kdelibs|3.5}}. Then you only need to create a DCOPRef to the object&lt;br /&gt;
and as long as the function does not use unusual argument types,&lt;br /&gt;
calling the function is as easy as this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
DCOPRef barObject (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;);&lt;br /&gt;
DCOPReply reply = barObject. call (&amp;quot;doIt&amp;quot;, 5);&lt;br /&gt;
if (!reply. isValid())&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    print(&amp;quot;the result is: %s&amp;quot;, ((QString)reply). latin1());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Receiving Data via DCOP ====&lt;br /&gt;
&lt;br /&gt;
Currently the only real way to receive data from DCOP is to multiply&lt;br /&gt;
inherit from the normal class that you are inheriting (usually some&lt;br /&gt;
sort of QWidget subclass or QObject) as well as the DCOPObject class.&lt;br /&gt;
DCOPObject provides one very important method: DCOPObject::process().&lt;br /&gt;
This is a pure virtual method that you must implement in order to&lt;br /&gt;
process DCOP messages that you receive.  It takes a function&lt;br /&gt;
signature, QByteArray of parameters, and a reference to a QByteArray&lt;br /&gt;
for the reply data that you must fill in.&lt;br /&gt;
&lt;br /&gt;
Think of DCOPObject::process() as a sort of dispatch agent.  In the&lt;br /&gt;
future, there will probably be a precompiler for your sources to write&lt;br /&gt;
this method for you.  However, until that point you need to examine&lt;br /&gt;
the incoming function signature and take action accordingly.  Here is&lt;br /&gt;
an example implementation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject:: process (const QCString &amp;amp;fun, const QByteArray &amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;replyType, QByteArray &amp;amp;replyData)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg (data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;gt;&amp;gt; i;&lt;br /&gt;
        QString result = self -&amp;gt; doIt (i);&lt;br /&gt;
        QDataStream reply (replyData, IO_WriteOnly);&lt;br /&gt;
        reply &amp;lt;&amp;lt; result;&lt;br /&gt;
        replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug (&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Processing Received Calls with Transactions ====&lt;br /&gt;
&lt;br /&gt;
If your applications is able to process incoming function calls&lt;br /&gt;
right away the above code is all you need. When your application&lt;br /&gt;
needs to do more complex tasks you might want to do the processing&lt;br /&gt;
out of 'process' function call and send the result back later when&lt;br /&gt;
it becomes available.&lt;br /&gt;
&lt;br /&gt;
For this you can ask your DCOPClient for a transactionId. You can&lt;br /&gt;
then return from the 'process' function and when the result is&lt;br /&gt;
available finish the transaction. In the mean time your application&lt;br /&gt;
can receive incoming DCOP function calls from other clients.&lt;br /&gt;
&lt;br /&gt;
Such code could like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject::process(const QCString &amp;amp;fun, const QByteArray &amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;, QByteArray &amp;amp;)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg (data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;gt;&amp;gt; i;&lt;br /&gt;
        QString result = self -&amp;gt; doIt(i);&lt;br /&gt;
&lt;br /&gt;
        DCOPClientTransaction *myTransaction;&lt;br /&gt;
        myTransaction = kapp -&amp;gt; dcopClient() -&amp;gt; beginTransaction();&lt;br /&gt;
&lt;br /&gt;
        // start processing...&lt;br /&gt;
        // Calls slotProcessingDone when finished.&lt;br /&gt;
        startProcessing (myTransaction, i);&lt;br /&gt;
&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug(&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
slotProcessingDone(DCOPClientTransaction *myTransaction, const QString &amp;amp;result)&lt;br /&gt;
{&lt;br /&gt;
    QCString replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
    QByteArray replyData;&lt;br /&gt;
    QDataStream reply(replyData, IO_WriteOnly);&lt;br /&gt;
    reply &amp;lt;&amp;lt; result;&lt;br /&gt;
    kapp &lt;br /&gt;
-&amp;gt; dcopClient() -&amp;gt; endTransaction(myTransaction, replyType, replyData);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DCOP Signals ====&lt;br /&gt;
&lt;br /&gt;
Sometimes a component wants to send notifications via DCOP to other&lt;br /&gt;
components but does not know which components will be interested in these&lt;br /&gt;
notifications. One could use a broadcast in such a case but this is a very&lt;br /&gt;
crude method. For a more sophisticated method DCOP signals have been invented.&lt;br /&gt;
&lt;br /&gt;
DCOP signals are very similair to Qt signals, there are some differences &lt;br /&gt;
though. A DCOP signal can be connected to a DCOP function. Whenever the DCOP&lt;br /&gt;
signal gets emitted, the DCOP functions to which the signal is connected are&lt;br /&gt;
being called. DCOP signals are, just like Qt signals, one way. They do not&lt;br /&gt;
provide a return value. &lt;br /&gt;
&lt;br /&gt;
A DCOP signal originates from a DCOP Object/DCOP Client combination (sender). &lt;br /&gt;
It can be connected to a function of another DCOP Object/DCOP Client &lt;br /&gt;
combination (receiver).&lt;br /&gt;
&lt;br /&gt;
There are two major differences between connections of Qt signals and&lt;br /&gt;
connections of DCOP signals. In DCOP, unlike Qt, a signal connections can&lt;br /&gt;
have an anonymous sender and, unlike Qt, a DCOP signal connection can be&lt;br /&gt;
non-volatile.&lt;br /&gt;
&lt;br /&gt;
With DCOP one can connect a signal without specifying the sending DCOP Object &lt;br /&gt;
or DCOP Client. In that case signals from any DCOP Object and/or DCOP Client&lt;br /&gt;
will be delivered. This allows the specification of certain events without&lt;br /&gt;
tying oneself to a certain object that implementes the events.&lt;br /&gt;
&lt;br /&gt;
Another DCOP feature are so called non-volatile connections. With Qt signal&lt;br /&gt;
connections, the connection gets deleted when either sender or receiver of&lt;br /&gt;
the signal gets deleted. A volatile DCOP signal connection will behave the&lt;br /&gt;
same. However, a non-volatile DCOP signal connection will not get deleted &lt;br /&gt;
when the sending object gets deleted. Once a new object gets created with &lt;br /&gt;
the same name as the original sending object, the connection will be restored.&lt;br /&gt;
There is no difference between the two when the receiving object gets deleted,&lt;br /&gt;
in that case the signal connection will always be deleted.&lt;br /&gt;
&lt;br /&gt;
A receiver can create a non-volatile connection while the sender doesn't (yet)&lt;br /&gt;
exist. An anonymous DCOP connection should always be non-volatile.&lt;br /&gt;
&lt;br /&gt;
The following example shows how KLauncher emits a signal whenever it notices&lt;br /&gt;
that an application that was started via KLauncher terminates.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray params;&lt;br /&gt;
QDataStream stream (params, IO_WriteOnly);&lt;br /&gt;
stream &amp;lt;&amp;lt; pid;&lt;br /&gt;
kapp -&amp;gt; dcopClient() -&amp;gt; emitDCOPSignal (&amp;quot;clientDied(pid_t)&amp;quot;, params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The task manager of the KDE panel connects to this signal. It uses an &lt;br /&gt;
anonymous connection (it doesn't require that the signal is being emitted&lt;br /&gt;
by KLauncher) that is non-volatile:&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
connectDCOPSignal (0, 0, &amp;quot;clientDied(pid_t)&amp;quot;, &amp;quot;clientDied(pid_t)&amp;quot;, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It connects the clientDied(pid_t) signal to its own clientDied(pid_t) DCOP&lt;br /&gt;
function. In this case the signal and the function to call have the same name.&lt;br /&gt;
This isn't needed as long as the arguments of both signal and receiving function&lt;br /&gt;
match. The receiving function may ignore one or more of the trailing arguments&lt;br /&gt;
of the signal. E.g. it is allowed to connect the clientDied(pid_t) signal to&lt;br /&gt;
a clientDied(void) DCOP function.&lt;br /&gt;
&lt;br /&gt;
=== Using the dcopidl compiler ===&lt;br /&gt;
&lt;br /&gt;
dcopidl makes setting up a DCOP server easy. Instead of having to implement&lt;br /&gt;
the process() method and unmarshalling (retrieving from QByteArray) parameters&lt;br /&gt;
manually, you can let dcopidl create the necessary code on your behalf.&lt;br /&gt;
&lt;br /&gt;
This also allows you to describe the interface for your class in a&lt;br /&gt;
single, separate header file.&lt;br /&gt;
&lt;br /&gt;
Writing an IDL file is very similar to writing a normal C++ header. An&lt;br /&gt;
exception is the keyword 'ASYNC'. It indicates that a call to this&lt;br /&gt;
function shall be processed asynchronously. For the C++ compiler, it&lt;br /&gt;
expands to 'void'.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#ifndef MY_INTERFACE_H&lt;br /&gt;
#define MY_INTERFACE_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;dcopobject.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class MyInterface : virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
&lt;br /&gt;
        virtual ASYNC myAsynchronousMethod (QString someParameter) = 0;&lt;br /&gt;
        virtual QRect mySynchronousMethod() = 0;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, you're essentially declaring an abstract base class, which&lt;br /&gt;
virtually inherits from DCOPObject.&lt;br /&gt;
&lt;br /&gt;
If you're using the standard KDE build scripts, then you can simply add this file (which you would call {{path|MyInterface.h}}) to your sources directory. Then you edit your {{path|Makefile.am}}, adding 'MyInterface.skel' to your SOURCES list and {{path|MyInterface.h}} to include_HEADERS.&lt;br /&gt;
&lt;br /&gt;
The build scripts will use dcopidl to parse {{path|MyInterface.h}}, converting it to an XML description in {{path|MyInterface.kidl}}. Next, a file called {{path|MyInterface_skel.cpp}} will automatically be created, compiled and linked with your binary.&lt;br /&gt;
&lt;br /&gt;
The next thing you have to do is to choose which of your classes will implement the interface described in {{path|MyInterface.h}}. Alter the inheritance of this class such that it virtually inherits from {{path|MyInterface}}. Then add declarations to your class interface similar to those on {{path|MyInterface.h}}, but virtual, not pure virtual.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public MyInterface&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: (Qt issue) Remember that if you are inheriting from {{qt3|QObject}}, you must place it first in the list of inherited classes.&lt;br /&gt;
&lt;br /&gt;
In the implementation of your class' ctor, you must explicitly initialize&lt;br /&gt;
those classes from which you are inheriting from. This is, of course, good&lt;br /&gt;
practise, but it is essential here as you need to tell DCOPObject the name of&lt;br /&gt;
the interface which your are implementing.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
MyClass::MyClass()&lt;br /&gt;
  : QObject(),&lt;br /&gt;
    DCOPObject(&amp;quot;MyInterface&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
    // whatever...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can simply implement the methods you have declared in your interface,&lt;br /&gt;
exactly the same as you would normally.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
void MyClass::myAsynchronousMethod(QString someParameter)&lt;br /&gt;
{&lt;br /&gt;
    qDebug(&amp;quot;myAsyncMethod called with param `&amp;quot; + someParameter + &amp;quot;'&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is not necessary (though very clean) to define an interface as an&lt;br /&gt;
abstract class of its own, like we did in the example above. We could&lt;br /&gt;
just as well have defined a k_dcop section directly within MyClass:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to skeletons, dcopidl2cpp also generate stubs. Those make&lt;br /&gt;
it easy to call a DCOP interface without doing the marshalling&lt;br /&gt;
manually. To use a stub, add {{path|MyInterface.stub}} to the SOURCES list of&lt;br /&gt;
your {{path|Makefile.am}}. The stub class will then be called MyInterface_stub.&lt;br /&gt;
&lt;br /&gt;
=== Inter-user communication ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it might be interesting to use DCOP between processes&lt;br /&gt;
belonging to different users, e.g. a frontend process running&lt;br /&gt;
with the user's id, and a backend process running as root.&lt;br /&gt;
&lt;br /&gt;
To do this, two steps have to be taken:&lt;br /&gt;
* both processes need to talk to the same DCOP server&lt;br /&gt;
* proper authentication must be ensured&lt;br /&gt;
&lt;br /&gt;
For the first step, you simply pass the server address (as&lt;br /&gt;
found in .DCOPserver) to the second process. For the authentication,&lt;br /&gt;
you can use the ICEAUTHORITY environment variable to tell the&lt;br /&gt;
second process where to find the authentication information.&lt;br /&gt;
(Note that this implies that the second process is able to&lt;br /&gt;
read the authentication file, so it will probably only work&lt;br /&gt;
if the second process runs as root. If it should run as another&lt;br /&gt;
user, a similar approach to what kdesu does with xauth must&lt;br /&gt;
be taken. In fact, it would be a very good idea to add DCOP&lt;br /&gt;
support to kdesu!)&lt;br /&gt;
&lt;br /&gt;
For example&lt;br /&gt;
 ICEAUTHORITY=~user/.ICEauthority kdesu root -c kcmroot -dcopserver `cat ~user/.DCOPserver`&lt;br /&gt;
&lt;br /&gt;
will, after kdesu got the root password, execute kcmroot as root, talking&lt;br /&gt;
to the user's dcop server.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' DCOP communication is not encrypted, so please do not&lt;br /&gt;
pass important information around this way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Performance Tests ==&lt;br /&gt;
&lt;br /&gt;
A few back-of-the-napkin tests folks:&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#include &amp;amp;lt;kapp.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    KApplication *app;&lt;br /&gt;
&lt;br /&gt;
    app = new KApplication(argc, argv, &amp;quot;testit&amp;quot;);&lt;br /&gt;
    return app-&amp;amp;gt;exec();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compiled with:&lt;br /&gt;
 g++ -O2 -o testit testit.cpp -I$QTDIR/include -L$QTDIR/lib -lkdecore&lt;br /&gt;
&lt;br /&gt;
on Linux yields the following memory use statistics:&lt;br /&gt;
 VmSize:     8076 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4532 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
If I create the KApplication's DCOPClient, and call attach() and&lt;br /&gt;
registerAs(), it changes to this:&lt;br /&gt;
 VmSize:     8080 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4624 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
Basically it appears that using DCOP causes 100k more memory to be&lt;br /&gt;
resident, but no more data or stack.  So this will be shared between all&lt;br /&gt;
processes, right?  100k to enable DCOP in all apps doesn't seem bad at&lt;br /&gt;
all. :)&lt;br /&gt;
&lt;br /&gt;
OK now for some timings.  Just creating a KApplication and then exiting&lt;br /&gt;
(i.e. removing the call to KApplication::exec) takes this much time:&lt;br /&gt;
&lt;br /&gt;
 0.28user 0.02system 0:00.32elapsed 92%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1084major+62minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second on my PII-233.  Now, if we create our DCOP&lt;br /&gt;
object and attach to the server, it takes this long:&lt;br /&gt;
&lt;br /&gt;
 0.27user 0.03system 0:00.34elapsed 87%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1107major+65minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second.  Basically DCOPClient creation and attaching&lt;br /&gt;
gets lost in the statistical variation (&amp;quot;noise&amp;quot;).  I was getting times&lt;br /&gt;
between .32 and .48 over several runs for both of the example programs, so&lt;br /&gt;
obviously system load is more relevant than the extra two calls to&lt;br /&gt;
DCOPClient::attach and DCOPClient::registerAs, as well as the actual&lt;br /&gt;
DCOPClient constructor time.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Hopefully this document will get you well on your way into the world&lt;br /&gt;
of inter-process communication with KDE! Please direct all comments&lt;br /&gt;
and/or suggestions to [mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] and [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;].&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE3]]&lt;br /&gt;
[[Category:Architecture]]&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/DCOP</id>
		<title>Development/Architecture/DCOP</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/DCOP"/>
				<updated>2010-05-22T22:13:46Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* DCOP Signals */ replace entities&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;border: 1px solid #2090ff; padding: 1em 1em 1em 1em; background-color:#f8f8ff; align:center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DCOP: Desktop COmmunications Protocol'''&lt;br /&gt;
&lt;br /&gt;
[mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] October 14, 1999&lt;br /&gt;
&lt;br /&gt;
Revised and extended by [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;] Mar 29, 2000&lt;br /&gt;
&lt;br /&gt;
HTMLized by Hans Meine [mailto:rastajoe@gmx.net Hans Meine &amp;amp;lt;rastajoe@gmx.net&amp;amp;gt;] May 25, 2000&lt;br /&gt;
&lt;br /&gt;
Added a DCOPRef example: Tim Jansen May 12, 2003&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Demotivation and Background ==&lt;br /&gt;
&lt;br /&gt;
'''Note that new features may not be developed for DCOP. The successor for DCOP is D-Bus'''&lt;br /&gt;
&lt;br /&gt;
The motivation behind building a protocol like DCOP is simple.  For&lt;br /&gt;
the past year, we have been attempting to enable interprocess&lt;br /&gt;
communication between KDE applications. KDE already has an extremely&lt;br /&gt;
simple IPC mechanism called KWMcom, which is (was!) used for communicating&lt;br /&gt;
between the panel and the window manager for instance.  It is about as&lt;br /&gt;
simple as it gets, passing messages via X Atoms.  For this reason it&lt;br /&gt;
is limited in the size and complexity of the data that can be passed&lt;br /&gt;
(X atoms must be small to remain efficient) and it also makes it so&lt;br /&gt;
that X is required.  CORBA was thought to be a more effective IPC/RPC&lt;br /&gt;
solution.  However, after a year of attempting to make heavy use of&lt;br /&gt;
CORBA in KDE, we have realized that it is a bit slow and memory&lt;br /&gt;
intensive for simple use.  It also has no authentication available.&lt;br /&gt;
&lt;br /&gt;
What we really needed was an extremely simple protocol with basic&lt;br /&gt;
authorization, along the lines of MIT-MAGIC-COOKIE, as used by X.  It&lt;br /&gt;
would not be able to do NEARLY what CORBA was able to do, but for the&lt;br /&gt;
simple tasks required it would be sufficient. Some examples of such&lt;br /&gt;
tasks might be an application sending a message to the panel saying,&lt;br /&gt;
&amp;quot;I have started, stop displaying the 'application starting' wait&lt;br /&gt;
state,&amp;quot; or having a new application that starts query to see if any&lt;br /&gt;
other applications of the same name are running.  If they are, simply&lt;br /&gt;
call a function on the remote application to create a new window,&lt;br /&gt;
rather than starting a new process.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
DCOP is a simple IPC/RPC mechanism built to operate over sockets.&lt;br /&gt;
Either unix domain sockets or tcp/ip sockets are supported. DCOP is&lt;br /&gt;
built on top of the Inter Client Exchange (ICE) protocol, which comes&lt;br /&gt;
standard as a part of X11R6 and later. It also depends on Qt, but&lt;br /&gt;
beyond that it does not require any other libraries. Because of this,&lt;br /&gt;
it is extremely lightweight, enabling it to be linked into all KDE&lt;br /&gt;
applications with low overhead.&lt;br /&gt;
&lt;br /&gt;
=== Model ===&lt;br /&gt;
&lt;br /&gt;
The model is simple.  Each application using DCOP is a client.  They&lt;br /&gt;
communicate to each other through a DCOP server, which functions like&lt;br /&gt;
a traffic director, dispatching messages/calls to the proper&lt;br /&gt;
destinations.  All clients are peers of each other.&lt;br /&gt;
&lt;br /&gt;
Two types of actions are possible with DCOP: &amp;quot;send and forget&amp;quot;&lt;br /&gt;
messages, which do not block, and &amp;quot;calls,&amp;quot; which block waiting for&lt;br /&gt;
some data to be returned.&lt;br /&gt;
&lt;br /&gt;
Any data that will be sent is serialized (marshalled, for you CORBA&lt;br /&gt;
fellows) using the built-in {{qt3|QDataStream}} operators available in all of&lt;br /&gt;
the Qt classes.  This is fast and easy.  In fact it's so little work&lt;br /&gt;
that you can easily write the marshalling code by hand. In addition,&lt;br /&gt;
there's a simple IDL-like compiler available (dcopidl and dcopidl2cpp)&lt;br /&gt;
that generates stubs and skeletons for you. Using the dcopidl compiler&lt;br /&gt;
has the additional benefit of type safety.&lt;br /&gt;
&lt;br /&gt;
This HOWTO describes the manual method first and covers the dcopidl&lt;br /&gt;
compiler later.&lt;br /&gt;
&lt;br /&gt;
=== Managing DCOP Connections Manually ===&lt;br /&gt;
&lt;br /&gt;
==== Establishing the Connection ====&lt;br /&gt;
&lt;br /&gt;
{{class|KApplication|kdelibs|3.5}} has gained a method called &amp;quot;KApplication::dcopClient()&amp;quot;&lt;br /&gt;
which returns a pointer to a DCOPClient instance.  The first time this&lt;br /&gt;
method is called, the client class will be created.  {{class|DCOPClient|kdelibs|3.5}}s have&lt;br /&gt;
unique identifiers attached to them which are based on what&lt;br /&gt;
KApplication::name() returns.  In fact, if there is only a single&lt;br /&gt;
instance of the program running, the appId will be equal to&lt;br /&gt;
KApplication::name().&lt;br /&gt;
&lt;br /&gt;
To actually enable DCOP communication to begin, you must use&lt;br /&gt;
DCOPClient::attach().  This will attempt to attach to the DCOP server.&lt;br /&gt;
If no server is found or there is any other type of error, attach()&lt;br /&gt;
will return false. KApplication will catch a dcop signal and display an&lt;br /&gt;
appropriate error message box in that case.&lt;br /&gt;
&lt;br /&gt;
After connecting with the server via DCOPClient::attach(), you need to&lt;br /&gt;
register this appId with the server so it knows about you.  Otherwise,&lt;br /&gt;
you are communicating anonymously.  Use the&lt;br /&gt;
DCOPClient::registerAs(const QCString &amp;amp;amp;name) to do so.  In the simple&lt;br /&gt;
case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * returns the appId that is actually registered, which _may_ be&lt;br /&gt;
 * different from what you passed&lt;br /&gt;
 */&lt;br /&gt;
appId = client -&amp;gt; registerAs (kApp -&amp;gt; name());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you never retrieve the DCOPClient pointer from KApplication, the&lt;br /&gt;
object will not be created and thus there will be no memory overhead.&lt;br /&gt;
&lt;br /&gt;
You may also detach from the server by calling DCOPClient::detach().&lt;br /&gt;
If you wish to attach again you will need to re-register as well.  If&lt;br /&gt;
you only wish to change the ID under which you are registered, simply&lt;br /&gt;
call DCOPClient::registerAs() with the new name.&lt;br /&gt;
&lt;br /&gt;
KUniqueApplication automatically registers itself to DCOP. If you&lt;br /&gt;
are using KUniqueApplication you should not attach or register&lt;br /&gt;
yourself, this is already done. The appId is by definition&lt;br /&gt;
equal to kapp-&amp;amp;gt;name(). You can retrieve the registered DCOP client&lt;br /&gt;
by calling kapp-&amp;amp;gt;dcopClient().&lt;br /&gt;
&lt;br /&gt;
==== Sending Data to a Remote Application ====&lt;br /&gt;
&lt;br /&gt;
To actually communicate, you have one of two choices.  You may either&lt;br /&gt;
call the &amp;quot;send&amp;quot; or the &amp;quot;call&amp;quot; method.  Both methods require three&lt;br /&gt;
identification parameters: an application identifier, a remote object,&lt;br /&gt;
a remote function. Sending is asynchronous (i.e. it returns immediately)&lt;br /&gt;
and may or may not result in your own application being sent a message at&lt;br /&gt;
some point in the future. Then &amp;quot;send&amp;quot; requires one and &amp;quot;call&amp;quot; requires&lt;br /&gt;
two data parameters.&lt;br /&gt;
&lt;br /&gt;
The remote object must be specified as an object hierarchy.  That is,&lt;br /&gt;
if the toplevel object is called &amp;quot;fooObject&amp;quot; and has the child&lt;br /&gt;
&amp;quot;barObject&amp;quot;, you would reference this object as &amp;quot;fooObject/barObject&amp;quot;.&lt;br /&gt;
Functions must be described by a full function signature.  If the&lt;br /&gt;
remote function is called &amp;quot;doIt&amp;quot;, and it takes an int, it would be&lt;br /&gt;
described as &amp;quot;doIt(int)&amp;quot;.  Please note that the return type is not&lt;br /&gt;
specified here, as it is not part of the function signature (or at&lt;br /&gt;
least the C++ understanding of a function signature).  You will get&lt;br /&gt;
the return type of a function back as an extra parameter to&lt;br /&gt;
DCOPClient::call().  See the section on call() for more details.&lt;br /&gt;
&lt;br /&gt;
In order to actually get the data to the remote client, it must be&lt;br /&gt;
&amp;quot;serialized&amp;quot; via a {{qt3|QDataStream}} operating on a {{qt3|QByteArray}}. This is how&lt;br /&gt;
the data parameter is &amp;quot;built&amp;quot;. A few examples will make clear how this&lt;br /&gt;
works.&lt;br /&gt;
&lt;br /&gt;
Say you want to call &amp;quot;doIt&amp;quot; as described above, and not block (or wait&lt;br /&gt;
for a response).  You will not receive the return value of the remotely&lt;br /&gt;
called function, but you will not hang while the RPC is processed either.&lt;br /&gt;
The return value of send() indicates whether DCOP communication succeeded&lt;br /&gt;
or not.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data;&lt;br /&gt;
QDataStream arg(data, IO_WriteOnly);&lt;br /&gt;
arg &amp;lt;&amp;lt; 5;&lt;br /&gt;
if (!client -&amp;gt; send (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data))&lt;br /&gt;
    qDebug (&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OK, now let's say we wanted to get the data back from the remotely&lt;br /&gt;
called function.  You have to execute a call() instead of a send().&lt;br /&gt;
The returned value will then be available in the data parameter &amp;quot;reply&amp;quot;.&lt;br /&gt;
The actual return value of call() is still whether or not DCOP&lt;br /&gt;
communication was successful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data, replyData;&lt;br /&gt;
QCString replyType;&lt;br /&gt;
QDataStream arg (data, IO_WriteOnly);&lt;br /&gt;
arg &amp;lt;&amp;lt; 5;&lt;br /&gt;
if (!client -&amp;gt; call (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data, replyType, replyData))&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    QDataStream reply (replyData, IO_ReadOnly);&lt;br /&gt;
    if (replyType == &amp;quot;QString&amp;quot;) {&lt;br /&gt;
        QString result;&lt;br /&gt;
        reply &amp;gt;&amp;gt; result;&lt;br /&gt;
        print (&amp;quot;the result is: %s&amp;quot;, result. latin1());&lt;br /&gt;
    } else&lt;br /&gt;
        qDebug (&amp;quot;doIt returned an unexpected type of reply!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''N.B.:'' You cannot call() a method belonging to an application which has&lt;br /&gt;
registered with an unique numeric id appended to its textual name (see&lt;br /&gt;
dcopclient.h for more info). In this case, DCOP would not know which&lt;br /&gt;
application it should connect with to call the method. This is not an issue&lt;br /&gt;
with send(), as you can broadcast to all applications that have registered&lt;br /&gt;
with appname-&amp;amp;lt;numeric_id&amp;amp;gt; by using a wildcard (e.g. 'konsole-*'), which&lt;br /&gt;
will send your signal to all applications called 'konsole'.&lt;br /&gt;
&lt;br /&gt;
Since KDE 3.1 there is an even easier way to make a DCOP call:&lt;br /&gt;
{{class|DCOPRef|kdelibs|3.5}}. Then you only need to create a DCOPRef to the object&lt;br /&gt;
and as long as the function does not use unusual argument types,&lt;br /&gt;
calling the function is as easy as this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
DCOPRef barObject (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;);&lt;br /&gt;
DCOPReply reply = barObject. call (&amp;quot;doIt&amp;quot;, 5);&lt;br /&gt;
if (!reply. isValid())&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    print(&amp;quot;the result is: %s&amp;quot;, ((QString)reply). latin1());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Receiving Data via DCOP ====&lt;br /&gt;
&lt;br /&gt;
Currently the only real way to receive data from DCOP is to multiply&lt;br /&gt;
inherit from the normal class that you are inheriting (usually some&lt;br /&gt;
sort of QWidget subclass or QObject) as well as the DCOPObject class.&lt;br /&gt;
DCOPObject provides one very important method: DCOPObject::process().&lt;br /&gt;
This is a pure virtual method that you must implement in order to&lt;br /&gt;
process DCOP messages that you receive.  It takes a function&lt;br /&gt;
signature, QByteArray of parameters, and a reference to a QByteArray&lt;br /&gt;
for the reply data that you must fill in.&lt;br /&gt;
&lt;br /&gt;
Think of DCOPObject::process() as a sort of dispatch agent.  In the&lt;br /&gt;
future, there will probably be a precompiler for your sources to write&lt;br /&gt;
this method for you.  However, until that point you need to examine&lt;br /&gt;
the incoming function signature and take action accordingly.  Here is&lt;br /&gt;
an example implementation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject:: process (const QCString &amp;amp;fun, const QByteArray &amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;replyType, QByteArray &amp;amp;replyData)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg (data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;gt;&amp;gt; i;&lt;br /&gt;
        QString result = self -&amp;gt; doIt (i);&lt;br /&gt;
        QDataStream reply (replyData, IO_WriteOnly);&lt;br /&gt;
        reply &amp;lt;&amp;lt; result;&lt;br /&gt;
        replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug (&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Processing Received Calls with Transactions ====&lt;br /&gt;
&lt;br /&gt;
If your applications is able to process incoming function calls&lt;br /&gt;
right away the above code is all you need. When your application&lt;br /&gt;
needs to do more complex tasks you might want to do the processing&lt;br /&gt;
out of 'process' function call and send the result back later when&lt;br /&gt;
it becomes available.&lt;br /&gt;
&lt;br /&gt;
For this you can ask your DCOPClient for a transactionId. You can&lt;br /&gt;
then return from the 'process' function and when the result is&lt;br /&gt;
available finish the transaction. In the mean time your application&lt;br /&gt;
can receive incoming DCOP function calls from other clients.&lt;br /&gt;
&lt;br /&gt;
Such code could like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject::process(const QCString &amp;amp;fun, const QByteArray &amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;, QByteArray &amp;amp;)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg (data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;gt;&amp;gt; i;&lt;br /&gt;
        QString result = self -&amp;gt; doIt(i);&lt;br /&gt;
&lt;br /&gt;
        DCOPClientTransaction *myTransaction;&lt;br /&gt;
        myTransaction = kapp -&amp;gt; dcopClient() -&amp;gt; beginTransaction();&lt;br /&gt;
&lt;br /&gt;
        // start processing...&lt;br /&gt;
        // Calls slotProcessingDone when finished.&lt;br /&gt;
        startProcessing (myTransaction, i);&lt;br /&gt;
&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug(&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
slotProcessingDone(DCOPClientTransaction *myTransaction, const QString &amp;amp;result)&lt;br /&gt;
{&lt;br /&gt;
    QCString replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
    QByteArray replyData;&lt;br /&gt;
    QDataStream reply(replyData, IO_WriteOnly);&lt;br /&gt;
    reply &amp;lt;&amp;lt; result;&lt;br /&gt;
    kapp &lt;br /&gt;
-&amp;gt; dcopClient() -&amp;gt; endTransaction(myTransaction, replyType, replyData);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DCOP Signals ====&lt;br /&gt;
&lt;br /&gt;
Sometimes a component wants to send notifications via DCOP to other&lt;br /&gt;
components but does not know which components will be interested in these&lt;br /&gt;
notifications. One could use a broadcast in such a case but this is a very&lt;br /&gt;
crude method. For a more sophisticated method DCOP signals have been invented.&lt;br /&gt;
&lt;br /&gt;
DCOP signals are very similair to Qt signals, there are some differences &lt;br /&gt;
though. A DCOP signal can be connected to a DCOP function. Whenever the DCOP&lt;br /&gt;
signal gets emitted, the DCOP functions to which the signal is connected are&lt;br /&gt;
being called. DCOP signals are, just like Qt signals, one way. They do not&lt;br /&gt;
provide a return value. &lt;br /&gt;
&lt;br /&gt;
A DCOP signal originates from a DCOP Object/DCOP Client combination (sender). &lt;br /&gt;
It can be connected to a function of another DCOP Object/DCOP Client &lt;br /&gt;
combination (receiver).&lt;br /&gt;
&lt;br /&gt;
There are two major differences between connections of Qt signals and&lt;br /&gt;
connections of DCOP signals. In DCOP, unlike Qt, a signal connections can&lt;br /&gt;
have an anonymous sender and, unlike Qt, a DCOP signal connection can be&lt;br /&gt;
non-volatile.&lt;br /&gt;
&lt;br /&gt;
With DCOP one can connect a signal without specifying the sending DCOP Object &lt;br /&gt;
or DCOP Client. In that case signals from any DCOP Object and/or DCOP Client&lt;br /&gt;
will be delivered. This allows the specification of certain events without&lt;br /&gt;
tying oneself to a certain object that implementes the events.&lt;br /&gt;
&lt;br /&gt;
Another DCOP feature are so called non-volatile connections. With Qt signal&lt;br /&gt;
connections, the connection gets deleted when either sender or receiver of&lt;br /&gt;
the signal gets deleted. A volatile DCOP signal connection will behave the&lt;br /&gt;
same. However, a non-volatile DCOP signal connection will not get deleted &lt;br /&gt;
when the sending object gets deleted. Once a new object gets created with &lt;br /&gt;
the same name as the original sending object, the connection will be restored.&lt;br /&gt;
There is no difference between the two when the receiving object gets deleted,&lt;br /&gt;
in that case the signal connection will always be deleted.&lt;br /&gt;
&lt;br /&gt;
A receiver can create a non-volatile connection while the sender doesn't (yet)&lt;br /&gt;
exist. An anonymous DCOP connection should always be non-volatile.&lt;br /&gt;
&lt;br /&gt;
The following example shows how KLauncher emits a signal whenever it notices&lt;br /&gt;
that an application that was started via KLauncher terminates.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray params;&lt;br /&gt;
QDataStream stream (params, IO_WriteOnly);&lt;br /&gt;
stream &amp;lt;&amp;lt; pid;&lt;br /&gt;
kapp -&amp;gt; dcopClient() -&amp;gt; emitDCOPSignal (&amp;quot;clientDied(pid_t)&amp;quot;, params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The task manager of the KDE panel connects to this signal. It uses an &lt;br /&gt;
anonymous connection (it doesn't require that the signal is being emitted&lt;br /&gt;
by KLauncher) that is non-volatile:&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
connectDCOPSignal (0, 0, &amp;quot;clientDied(pid_t)&amp;quot;, &amp;quot;clientDied(pid_t)&amp;quot;, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It connects the clientDied(pid_t) signal to its own clientDied(pid_t) DCOP&lt;br /&gt;
function. In this case the signal and the function to call have the same name.&lt;br /&gt;
This isn't needed as long as the arguments of both signal and receiving function&lt;br /&gt;
match. The receiving function may ignore one or more of the trailing arguments&lt;br /&gt;
of the signal. E.g. it is allowed to connect the clientDied(pid_t) signal to&lt;br /&gt;
a clientDied(void) DCOP function.&lt;br /&gt;
&lt;br /&gt;
=== Using the dcopidl compiler ===&lt;br /&gt;
&lt;br /&gt;
dcopidl makes setting up a DCOP server easy. Instead of having to implement&lt;br /&gt;
the process() method and unmarshalling (retrieving from QByteArray) parameters&lt;br /&gt;
manually, you can let dcopidl create the necessary code on your behalf.&lt;br /&gt;
&lt;br /&gt;
This also allows you to describe the interface for your class in a&lt;br /&gt;
single, separate header file.&lt;br /&gt;
&lt;br /&gt;
Writing an IDL file is very similar to writing a normal C++ header. An&lt;br /&gt;
exception is the keyword 'ASYNC'. It indicates that a call to this&lt;br /&gt;
function shall be processed asynchronously. For the C++ compiler, it&lt;br /&gt;
expands to 'void'.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#ifndef MY_INTERFACE_H&lt;br /&gt;
#define MY_INTERFACE_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;amp;lt;dcopobject.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
class MyInterface : virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
&lt;br /&gt;
        virtual ASYNC myAsynchronousMethod(QString someParameter) = 0;&lt;br /&gt;
        virtual QRect mySynchronousMethod() = 0;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, you're essentially declaring an abstract base class, which&lt;br /&gt;
virtually inherits from DCOPObject.&lt;br /&gt;
&lt;br /&gt;
If you're using the standard KDE build scripts, then you can simply add this file (which you would call {{path|MyInterface.h}}) to your sources directory. Then you edit your {{path|Makefile.am}}, adding 'MyInterface.skel' to your SOURCES list and {{path|MyInterface.h}} to include_HEADERS.&lt;br /&gt;
&lt;br /&gt;
The build scripts will use dcopidl to parse {{path|MyInterface.h}}, converting it to an XML description in {{path|MyInterface.kidl}}. Next, a file called {{path|MyInterface_skel.cpp}} will automatically be created, compiled and linked with your binary.&lt;br /&gt;
&lt;br /&gt;
The next thing you have to do is to choose which of your classes will implement the interface described in {{path|MyInterface.h}}. Alter the inheritance of this class such that it virtually inherits from {{path|MyInterface}}. Then add declarations to your class interface similar to those on {{path|MyInterface.h}}, but virtual, not pure virtual.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public MyInterface&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: (Qt issue) Remember that if you are inheriting from {{qt3|QObject}}, you must place it first in the list of inherited classes.&lt;br /&gt;
&lt;br /&gt;
In the implementation of your class' ctor, you must explicitly initialize&lt;br /&gt;
those classes from which you are inheriting from. This is, of course, good&lt;br /&gt;
practise, but it is essential here as you need to tell DCOPObject the name of&lt;br /&gt;
the interface which your are implementing.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
MyClass::MyClass()&lt;br /&gt;
  : QObject(),&lt;br /&gt;
    DCOPObject(&amp;quot;MyInterface&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
    // whatever...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can simply implement the methods you have declared in your interface,&lt;br /&gt;
exactly the same as you would normally.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
void MyClass::myAsynchronousMethod(QString someParameter)&lt;br /&gt;
{&lt;br /&gt;
    qDebug(&amp;quot;myAsyncMethod called with param `&amp;quot; + someParameter + &amp;quot;'&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is not necessary (though very clean) to define an interface as an&lt;br /&gt;
abstract class of its own, like we did in the example above. We could&lt;br /&gt;
just as well have defined a k_dcop section directly within MyClass:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to skeletons, dcopidl2cpp also generate stubs. Those make&lt;br /&gt;
it easy to call a DCOP interface without doing the marshalling&lt;br /&gt;
manually. To use a stub, add {{path|MyInterface.stub}} to the SOURCES list of&lt;br /&gt;
your {{path|Makefile.am}}. The stub class will then be called MyInterface_stub.&lt;br /&gt;
&lt;br /&gt;
=== Inter-user communication ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it might be interesting to use DCOP between processes&lt;br /&gt;
belonging to different users, e.g. a frontend process running&lt;br /&gt;
with the user's id, and a backend process running as root.&lt;br /&gt;
&lt;br /&gt;
To do this, two steps have to be taken:&lt;br /&gt;
* both processes need to talk to the same DCOP server&lt;br /&gt;
* proper authentication must be ensured&lt;br /&gt;
&lt;br /&gt;
For the first step, you simply pass the server address (as&lt;br /&gt;
found in .DCOPserver) to the second process. For the authentication,&lt;br /&gt;
you can use the ICEAUTHORITY environment variable to tell the&lt;br /&gt;
second process where to find the authentication information.&lt;br /&gt;
(Note that this implies that the second process is able to&lt;br /&gt;
read the authentication file, so it will probably only work&lt;br /&gt;
if the second process runs as root. If it should run as another&lt;br /&gt;
user, a similar approach to what kdesu does with xauth must&lt;br /&gt;
be taken. In fact, it would be a very good idea to add DCOP&lt;br /&gt;
support to kdesu!)&lt;br /&gt;
&lt;br /&gt;
For example&lt;br /&gt;
 ICEAUTHORITY=~user/.ICEauthority kdesu root -c kcmroot -dcopserver `cat ~user/.DCOPserver`&lt;br /&gt;
&lt;br /&gt;
will, after kdesu got the root password, execute kcmroot as root, talking&lt;br /&gt;
to the user's dcop server.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' DCOP communication is not encrypted, so please do not&lt;br /&gt;
pass important information around this way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Performance Tests ==&lt;br /&gt;
&lt;br /&gt;
A few back-of-the-napkin tests folks:&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#include &amp;amp;lt;kapp.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    KApplication *app;&lt;br /&gt;
&lt;br /&gt;
    app = new KApplication(argc, argv, &amp;quot;testit&amp;quot;);&lt;br /&gt;
    return app-&amp;amp;gt;exec();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compiled with:&lt;br /&gt;
 g++ -O2 -o testit testit.cpp -I$QTDIR/include -L$QTDIR/lib -lkdecore&lt;br /&gt;
&lt;br /&gt;
on Linux yields the following memory use statistics:&lt;br /&gt;
 VmSize:     8076 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4532 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
If I create the KApplication's DCOPClient, and call attach() and&lt;br /&gt;
registerAs(), it changes to this:&lt;br /&gt;
 VmSize:     8080 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4624 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
Basically it appears that using DCOP causes 100k more memory to be&lt;br /&gt;
resident, but no more data or stack.  So this will be shared between all&lt;br /&gt;
processes, right?  100k to enable DCOP in all apps doesn't seem bad at&lt;br /&gt;
all. :)&lt;br /&gt;
&lt;br /&gt;
OK now for some timings.  Just creating a KApplication and then exiting&lt;br /&gt;
(i.e. removing the call to KApplication::exec) takes this much time:&lt;br /&gt;
&lt;br /&gt;
 0.28user 0.02system 0:00.32elapsed 92%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1084major+62minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second on my PII-233.  Now, if we create our DCOP&lt;br /&gt;
object and attach to the server, it takes this long:&lt;br /&gt;
&lt;br /&gt;
 0.27user 0.03system 0:00.34elapsed 87%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1107major+65minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second.  Basically DCOPClient creation and attaching&lt;br /&gt;
gets lost in the statistical variation (&amp;quot;noise&amp;quot;).  I was getting times&lt;br /&gt;
between .32 and .48 over several runs for both of the example programs, so&lt;br /&gt;
obviously system load is more relevant than the extra two calls to&lt;br /&gt;
DCOPClient::attach and DCOPClient::registerAs, as well as the actual&lt;br /&gt;
DCOPClient constructor time.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Hopefully this document will get you well on your way into the world&lt;br /&gt;
of inter-process communication with KDE! Please direct all comments&lt;br /&gt;
and/or suggestions to [mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] and [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;].&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE3]]&lt;br /&gt;
[[Category:Architecture]]&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/DCOP</id>
		<title>Development/Architecture/DCOP</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/DCOP"/>
				<updated>2010-05-22T22:12:10Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Processing Received Calls with Transactions */ replace entities&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;border: 1px solid #2090ff; padding: 1em 1em 1em 1em; background-color:#f8f8ff; align:center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DCOP: Desktop COmmunications Protocol'''&lt;br /&gt;
&lt;br /&gt;
[mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] October 14, 1999&lt;br /&gt;
&lt;br /&gt;
Revised and extended by [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;] Mar 29, 2000&lt;br /&gt;
&lt;br /&gt;
HTMLized by Hans Meine [mailto:rastajoe@gmx.net Hans Meine &amp;amp;lt;rastajoe@gmx.net&amp;amp;gt;] May 25, 2000&lt;br /&gt;
&lt;br /&gt;
Added a DCOPRef example: Tim Jansen May 12, 2003&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Demotivation and Background ==&lt;br /&gt;
&lt;br /&gt;
'''Note that new features may not be developed for DCOP. The successor for DCOP is D-Bus'''&lt;br /&gt;
&lt;br /&gt;
The motivation behind building a protocol like DCOP is simple.  For&lt;br /&gt;
the past year, we have been attempting to enable interprocess&lt;br /&gt;
communication between KDE applications. KDE already has an extremely&lt;br /&gt;
simple IPC mechanism called KWMcom, which is (was!) used for communicating&lt;br /&gt;
between the panel and the window manager for instance.  It is about as&lt;br /&gt;
simple as it gets, passing messages via X Atoms.  For this reason it&lt;br /&gt;
is limited in the size and complexity of the data that can be passed&lt;br /&gt;
(X atoms must be small to remain efficient) and it also makes it so&lt;br /&gt;
that X is required.  CORBA was thought to be a more effective IPC/RPC&lt;br /&gt;
solution.  However, after a year of attempting to make heavy use of&lt;br /&gt;
CORBA in KDE, we have realized that it is a bit slow and memory&lt;br /&gt;
intensive for simple use.  It also has no authentication available.&lt;br /&gt;
&lt;br /&gt;
What we really needed was an extremely simple protocol with basic&lt;br /&gt;
authorization, along the lines of MIT-MAGIC-COOKIE, as used by X.  It&lt;br /&gt;
would not be able to do NEARLY what CORBA was able to do, but for the&lt;br /&gt;
simple tasks required it would be sufficient. Some examples of such&lt;br /&gt;
tasks might be an application sending a message to the panel saying,&lt;br /&gt;
&amp;quot;I have started, stop displaying the 'application starting' wait&lt;br /&gt;
state,&amp;quot; or having a new application that starts query to see if any&lt;br /&gt;
other applications of the same name are running.  If they are, simply&lt;br /&gt;
call a function on the remote application to create a new window,&lt;br /&gt;
rather than starting a new process.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
DCOP is a simple IPC/RPC mechanism built to operate over sockets.&lt;br /&gt;
Either unix domain sockets or tcp/ip sockets are supported. DCOP is&lt;br /&gt;
built on top of the Inter Client Exchange (ICE) protocol, which comes&lt;br /&gt;
standard as a part of X11R6 and later. It also depends on Qt, but&lt;br /&gt;
beyond that it does not require any other libraries. Because of this,&lt;br /&gt;
it is extremely lightweight, enabling it to be linked into all KDE&lt;br /&gt;
applications with low overhead.&lt;br /&gt;
&lt;br /&gt;
=== Model ===&lt;br /&gt;
&lt;br /&gt;
The model is simple.  Each application using DCOP is a client.  They&lt;br /&gt;
communicate to each other through a DCOP server, which functions like&lt;br /&gt;
a traffic director, dispatching messages/calls to the proper&lt;br /&gt;
destinations.  All clients are peers of each other.&lt;br /&gt;
&lt;br /&gt;
Two types of actions are possible with DCOP: &amp;quot;send and forget&amp;quot;&lt;br /&gt;
messages, which do not block, and &amp;quot;calls,&amp;quot; which block waiting for&lt;br /&gt;
some data to be returned.&lt;br /&gt;
&lt;br /&gt;
Any data that will be sent is serialized (marshalled, for you CORBA&lt;br /&gt;
fellows) using the built-in {{qt3|QDataStream}} operators available in all of&lt;br /&gt;
the Qt classes.  This is fast and easy.  In fact it's so little work&lt;br /&gt;
that you can easily write the marshalling code by hand. In addition,&lt;br /&gt;
there's a simple IDL-like compiler available (dcopidl and dcopidl2cpp)&lt;br /&gt;
that generates stubs and skeletons for you. Using the dcopidl compiler&lt;br /&gt;
has the additional benefit of type safety.&lt;br /&gt;
&lt;br /&gt;
This HOWTO describes the manual method first and covers the dcopidl&lt;br /&gt;
compiler later.&lt;br /&gt;
&lt;br /&gt;
=== Managing DCOP Connections Manually ===&lt;br /&gt;
&lt;br /&gt;
==== Establishing the Connection ====&lt;br /&gt;
&lt;br /&gt;
{{class|KApplication|kdelibs|3.5}} has gained a method called &amp;quot;KApplication::dcopClient()&amp;quot;&lt;br /&gt;
which returns a pointer to a DCOPClient instance.  The first time this&lt;br /&gt;
method is called, the client class will be created.  {{class|DCOPClient|kdelibs|3.5}}s have&lt;br /&gt;
unique identifiers attached to them which are based on what&lt;br /&gt;
KApplication::name() returns.  In fact, if there is only a single&lt;br /&gt;
instance of the program running, the appId will be equal to&lt;br /&gt;
KApplication::name().&lt;br /&gt;
&lt;br /&gt;
To actually enable DCOP communication to begin, you must use&lt;br /&gt;
DCOPClient::attach().  This will attempt to attach to the DCOP server.&lt;br /&gt;
If no server is found or there is any other type of error, attach()&lt;br /&gt;
will return false. KApplication will catch a dcop signal and display an&lt;br /&gt;
appropriate error message box in that case.&lt;br /&gt;
&lt;br /&gt;
After connecting with the server via DCOPClient::attach(), you need to&lt;br /&gt;
register this appId with the server so it knows about you.  Otherwise,&lt;br /&gt;
you are communicating anonymously.  Use the&lt;br /&gt;
DCOPClient::registerAs(const QCString &amp;amp;amp;name) to do so.  In the simple&lt;br /&gt;
case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * returns the appId that is actually registered, which _may_ be&lt;br /&gt;
 * different from what you passed&lt;br /&gt;
 */&lt;br /&gt;
appId = client -&amp;gt; registerAs (kApp -&amp;gt; name());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you never retrieve the DCOPClient pointer from KApplication, the&lt;br /&gt;
object will not be created and thus there will be no memory overhead.&lt;br /&gt;
&lt;br /&gt;
You may also detach from the server by calling DCOPClient::detach().&lt;br /&gt;
If you wish to attach again you will need to re-register as well.  If&lt;br /&gt;
you only wish to change the ID under which you are registered, simply&lt;br /&gt;
call DCOPClient::registerAs() with the new name.&lt;br /&gt;
&lt;br /&gt;
KUniqueApplication automatically registers itself to DCOP. If you&lt;br /&gt;
are using KUniqueApplication you should not attach or register&lt;br /&gt;
yourself, this is already done. The appId is by definition&lt;br /&gt;
equal to kapp-&amp;amp;gt;name(). You can retrieve the registered DCOP client&lt;br /&gt;
by calling kapp-&amp;amp;gt;dcopClient().&lt;br /&gt;
&lt;br /&gt;
==== Sending Data to a Remote Application ====&lt;br /&gt;
&lt;br /&gt;
To actually communicate, you have one of two choices.  You may either&lt;br /&gt;
call the &amp;quot;send&amp;quot; or the &amp;quot;call&amp;quot; method.  Both methods require three&lt;br /&gt;
identification parameters: an application identifier, a remote object,&lt;br /&gt;
a remote function. Sending is asynchronous (i.e. it returns immediately)&lt;br /&gt;
and may or may not result in your own application being sent a message at&lt;br /&gt;
some point in the future. Then &amp;quot;send&amp;quot; requires one and &amp;quot;call&amp;quot; requires&lt;br /&gt;
two data parameters.&lt;br /&gt;
&lt;br /&gt;
The remote object must be specified as an object hierarchy.  That is,&lt;br /&gt;
if the toplevel object is called &amp;quot;fooObject&amp;quot; and has the child&lt;br /&gt;
&amp;quot;barObject&amp;quot;, you would reference this object as &amp;quot;fooObject/barObject&amp;quot;.&lt;br /&gt;
Functions must be described by a full function signature.  If the&lt;br /&gt;
remote function is called &amp;quot;doIt&amp;quot;, and it takes an int, it would be&lt;br /&gt;
described as &amp;quot;doIt(int)&amp;quot;.  Please note that the return type is not&lt;br /&gt;
specified here, as it is not part of the function signature (or at&lt;br /&gt;
least the C++ understanding of a function signature).  You will get&lt;br /&gt;
the return type of a function back as an extra parameter to&lt;br /&gt;
DCOPClient::call().  See the section on call() for more details.&lt;br /&gt;
&lt;br /&gt;
In order to actually get the data to the remote client, it must be&lt;br /&gt;
&amp;quot;serialized&amp;quot; via a {{qt3|QDataStream}} operating on a {{qt3|QByteArray}}. This is how&lt;br /&gt;
the data parameter is &amp;quot;built&amp;quot;. A few examples will make clear how this&lt;br /&gt;
works.&lt;br /&gt;
&lt;br /&gt;
Say you want to call &amp;quot;doIt&amp;quot; as described above, and not block (or wait&lt;br /&gt;
for a response).  You will not receive the return value of the remotely&lt;br /&gt;
called function, but you will not hang while the RPC is processed either.&lt;br /&gt;
The return value of send() indicates whether DCOP communication succeeded&lt;br /&gt;
or not.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data;&lt;br /&gt;
QDataStream arg(data, IO_WriteOnly);&lt;br /&gt;
arg &amp;lt;&amp;lt; 5;&lt;br /&gt;
if (!client -&amp;gt; send (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data))&lt;br /&gt;
    qDebug (&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OK, now let's say we wanted to get the data back from the remotely&lt;br /&gt;
called function.  You have to execute a call() instead of a send().&lt;br /&gt;
The returned value will then be available in the data parameter &amp;quot;reply&amp;quot;.&lt;br /&gt;
The actual return value of call() is still whether or not DCOP&lt;br /&gt;
communication was successful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data, replyData;&lt;br /&gt;
QCString replyType;&lt;br /&gt;
QDataStream arg (data, IO_WriteOnly);&lt;br /&gt;
arg &amp;lt;&amp;lt; 5;&lt;br /&gt;
if (!client -&amp;gt; call (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data, replyType, replyData))&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    QDataStream reply (replyData, IO_ReadOnly);&lt;br /&gt;
    if (replyType == &amp;quot;QString&amp;quot;) {&lt;br /&gt;
        QString result;&lt;br /&gt;
        reply &amp;gt;&amp;gt; result;&lt;br /&gt;
        print (&amp;quot;the result is: %s&amp;quot;, result. latin1());&lt;br /&gt;
    } else&lt;br /&gt;
        qDebug (&amp;quot;doIt returned an unexpected type of reply!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''N.B.:'' You cannot call() a method belonging to an application which has&lt;br /&gt;
registered with an unique numeric id appended to its textual name (see&lt;br /&gt;
dcopclient.h for more info). In this case, DCOP would not know which&lt;br /&gt;
application it should connect with to call the method. This is not an issue&lt;br /&gt;
with send(), as you can broadcast to all applications that have registered&lt;br /&gt;
with appname-&amp;amp;lt;numeric_id&amp;amp;gt; by using a wildcard (e.g. 'konsole-*'), which&lt;br /&gt;
will send your signal to all applications called 'konsole'.&lt;br /&gt;
&lt;br /&gt;
Since KDE 3.1 there is an even easier way to make a DCOP call:&lt;br /&gt;
{{class|DCOPRef|kdelibs|3.5}}. Then you only need to create a DCOPRef to the object&lt;br /&gt;
and as long as the function does not use unusual argument types,&lt;br /&gt;
calling the function is as easy as this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
DCOPRef barObject (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;);&lt;br /&gt;
DCOPReply reply = barObject. call (&amp;quot;doIt&amp;quot;, 5);&lt;br /&gt;
if (!reply. isValid())&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    print(&amp;quot;the result is: %s&amp;quot;, ((QString)reply). latin1());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Receiving Data via DCOP ====&lt;br /&gt;
&lt;br /&gt;
Currently the only real way to receive data from DCOP is to multiply&lt;br /&gt;
inherit from the normal class that you are inheriting (usually some&lt;br /&gt;
sort of QWidget subclass or QObject) as well as the DCOPObject class.&lt;br /&gt;
DCOPObject provides one very important method: DCOPObject::process().&lt;br /&gt;
This is a pure virtual method that you must implement in order to&lt;br /&gt;
process DCOP messages that you receive.  It takes a function&lt;br /&gt;
signature, QByteArray of parameters, and a reference to a QByteArray&lt;br /&gt;
for the reply data that you must fill in.&lt;br /&gt;
&lt;br /&gt;
Think of DCOPObject::process() as a sort of dispatch agent.  In the&lt;br /&gt;
future, there will probably be a precompiler for your sources to write&lt;br /&gt;
this method for you.  However, until that point you need to examine&lt;br /&gt;
the incoming function signature and take action accordingly.  Here is&lt;br /&gt;
an example implementation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject:: process (const QCString &amp;amp;fun, const QByteArray &amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;replyType, QByteArray &amp;amp;replyData)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg (data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;gt;&amp;gt; i;&lt;br /&gt;
        QString result = self -&amp;gt; doIt (i);&lt;br /&gt;
        QDataStream reply (replyData, IO_WriteOnly);&lt;br /&gt;
        reply &amp;lt;&amp;lt; result;&lt;br /&gt;
        replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug (&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Processing Received Calls with Transactions ====&lt;br /&gt;
&lt;br /&gt;
If your applications is able to process incoming function calls&lt;br /&gt;
right away the above code is all you need. When your application&lt;br /&gt;
needs to do more complex tasks you might want to do the processing&lt;br /&gt;
out of 'process' function call and send the result back later when&lt;br /&gt;
it becomes available.&lt;br /&gt;
&lt;br /&gt;
For this you can ask your DCOPClient for a transactionId. You can&lt;br /&gt;
then return from the 'process' function and when the result is&lt;br /&gt;
available finish the transaction. In the mean time your application&lt;br /&gt;
can receive incoming DCOP function calls from other clients.&lt;br /&gt;
&lt;br /&gt;
Such code could like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject::process(const QCString &amp;amp;fun, const QByteArray &amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;, QByteArray &amp;amp;)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg (data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;gt;&amp;gt; i;&lt;br /&gt;
        QString result = self -&amp;gt; doIt(i);&lt;br /&gt;
&lt;br /&gt;
        DCOPClientTransaction *myTransaction;&lt;br /&gt;
        myTransaction = kapp -&amp;gt; dcopClient() -&amp;gt; beginTransaction();&lt;br /&gt;
&lt;br /&gt;
        // start processing...&lt;br /&gt;
        // Calls slotProcessingDone when finished.&lt;br /&gt;
        startProcessing (myTransaction, i);&lt;br /&gt;
&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug(&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
slotProcessingDone(DCOPClientTransaction *myTransaction, const QString &amp;amp;result)&lt;br /&gt;
{&lt;br /&gt;
    QCString replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
    QByteArray replyData;&lt;br /&gt;
    QDataStream reply(replyData, IO_WriteOnly);&lt;br /&gt;
    reply &amp;lt;&amp;lt; result;&lt;br /&gt;
    kapp &lt;br /&gt;
-&amp;gt; dcopClient() -&amp;gt; endTransaction(myTransaction, replyType, replyData);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DCOP Signals ====&lt;br /&gt;
&lt;br /&gt;
Sometimes a component wants to send notifications via DCOP to other&lt;br /&gt;
components but does not know which components will be interested in these&lt;br /&gt;
notifications. One could use a broadcast in such a case but this is a very&lt;br /&gt;
crude method. For a more sophisticated method DCOP signals have been invented.&lt;br /&gt;
&lt;br /&gt;
DCOP signals are very similair to Qt signals, there are some differences &lt;br /&gt;
though. A DCOP signal can be connected to a DCOP function. Whenever the DCOP&lt;br /&gt;
signal gets emitted, the DCOP functions to which the signal is connected are&lt;br /&gt;
being called. DCOP signals are, just like Qt signals, one way. They do not&lt;br /&gt;
provide a return value. &lt;br /&gt;
&lt;br /&gt;
A DCOP signal originates from a DCOP Object/DCOP Client combination (sender). &lt;br /&gt;
It can be connected to a function of another DCOP Object/DCOP Client &lt;br /&gt;
combination (receiver).&lt;br /&gt;
&lt;br /&gt;
There are two major differences between connections of Qt signals and&lt;br /&gt;
connections of DCOP signals. In DCOP, unlike Qt, a signal connections can&lt;br /&gt;
have an anonymous sender and, unlike Qt, a DCOP signal connection can be&lt;br /&gt;
non-volatile.&lt;br /&gt;
&lt;br /&gt;
With DCOP one can connect a signal without specifying the sending DCOP Object &lt;br /&gt;
or DCOP Client. In that case signals from any DCOP Object and/or DCOP Client&lt;br /&gt;
will be delivered. This allows the specification of certain events without&lt;br /&gt;
tying oneself to a certain object that implementes the events.&lt;br /&gt;
&lt;br /&gt;
Another DCOP feature are so called non-volatile connections. With Qt signal&lt;br /&gt;
connections, the connection gets deleted when either sender or receiver of&lt;br /&gt;
the signal gets deleted. A volatile DCOP signal connection will behave the&lt;br /&gt;
same. However, a non-volatile DCOP signal connection will not get deleted &lt;br /&gt;
when the sending object gets deleted. Once a new object gets created with &lt;br /&gt;
the same name as the original sending object, the connection will be restored.&lt;br /&gt;
There is no difference between the two when the receiving object gets deleted,&lt;br /&gt;
in that case the signal connection will always be deleted.&lt;br /&gt;
&lt;br /&gt;
A receiver can create a non-volatile connection while the sender doesn't (yet)&lt;br /&gt;
exist. An anonymous DCOP connection should always be non-volatile.&lt;br /&gt;
&lt;br /&gt;
The following example shows how KLauncher emits a signal whenever it notices&lt;br /&gt;
that an application that was started via KLauncher terminates.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray params;&lt;br /&gt;
QDataStream stream(params, IO_WriteOnly);&lt;br /&gt;
stream &amp;amp;lt;&amp;amp;lt; pid;&lt;br /&gt;
kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;emitDCOPSignal(&amp;quot;clientDied(pid_t)&amp;quot;, params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The task manager of the KDE panel connects to this signal. It uses an &lt;br /&gt;
anonymous connection (it doesn't require that the signal is being emitted&lt;br /&gt;
by KLauncher) that is non-volatile:&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
connectDCOPSignal(0, 0, &amp;quot;clientDied(pid_t)&amp;quot;, &amp;quot;clientDied(pid_t)&amp;quot;, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It connects the clientDied(pid_t) signal to its own clientDied(pid_t) DCOP&lt;br /&gt;
function. In this case the signal and the function to call have the same name.&lt;br /&gt;
This isn't needed as long as the arguments of both signal and receiving function&lt;br /&gt;
match. The receiving function may ignore one or more of the trailing arguments&lt;br /&gt;
of the signal. E.g. it is allowed to connect the clientDied(pid_t) signal to&lt;br /&gt;
a clientDied(void) DCOP function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the dcopidl compiler ===&lt;br /&gt;
&lt;br /&gt;
dcopidl makes setting up a DCOP server easy. Instead of having to implement&lt;br /&gt;
the process() method and unmarshalling (retrieving from QByteArray) parameters&lt;br /&gt;
manually, you can let dcopidl create the necessary code on your behalf.&lt;br /&gt;
&lt;br /&gt;
This also allows you to describe the interface for your class in a&lt;br /&gt;
single, separate header file.&lt;br /&gt;
&lt;br /&gt;
Writing an IDL file is very similar to writing a normal C++ header. An&lt;br /&gt;
exception is the keyword 'ASYNC'. It indicates that a call to this&lt;br /&gt;
function shall be processed asynchronously. For the C++ compiler, it&lt;br /&gt;
expands to 'void'.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#ifndef MY_INTERFACE_H&lt;br /&gt;
#define MY_INTERFACE_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;amp;lt;dcopobject.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
class MyInterface : virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
&lt;br /&gt;
        virtual ASYNC myAsynchronousMethod(QString someParameter) = 0;&lt;br /&gt;
        virtual QRect mySynchronousMethod() = 0;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, you're essentially declaring an abstract base class, which&lt;br /&gt;
virtually inherits from DCOPObject.&lt;br /&gt;
&lt;br /&gt;
If you're using the standard KDE build scripts, then you can simply add this file (which you would call {{path|MyInterface.h}}) to your sources directory. Then you edit your {{path|Makefile.am}}, adding 'MyInterface.skel' to your SOURCES list and {{path|MyInterface.h}} to include_HEADERS.&lt;br /&gt;
&lt;br /&gt;
The build scripts will use dcopidl to parse {{path|MyInterface.h}}, converting it to an XML description in {{path|MyInterface.kidl}}. Next, a file called {{path|MyInterface_skel.cpp}} will automatically be created, compiled and linked with your binary.&lt;br /&gt;
&lt;br /&gt;
The next thing you have to do is to choose which of your classes will implement the interface described in {{path|MyInterface.h}}. Alter the inheritance of this class such that it virtually inherits from {{path|MyInterface}}. Then add declarations to your class interface similar to those on {{path|MyInterface.h}}, but virtual, not pure virtual.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public MyInterface&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: (Qt issue) Remember that if you are inheriting from {{qt3|QObject}}, you must place it first in the list of inherited classes.&lt;br /&gt;
&lt;br /&gt;
In the implementation of your class' ctor, you must explicitly initialize&lt;br /&gt;
those classes from which you are inheriting from. This is, of course, good&lt;br /&gt;
practise, but it is essential here as you need to tell DCOPObject the name of&lt;br /&gt;
the interface which your are implementing.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
MyClass::MyClass()&lt;br /&gt;
  : QObject(),&lt;br /&gt;
    DCOPObject(&amp;quot;MyInterface&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
    // whatever...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can simply implement the methods you have declared in your interface,&lt;br /&gt;
exactly the same as you would normally.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
void MyClass::myAsynchronousMethod(QString someParameter)&lt;br /&gt;
{&lt;br /&gt;
    qDebug(&amp;quot;myAsyncMethod called with param `&amp;quot; + someParameter + &amp;quot;'&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is not necessary (though very clean) to define an interface as an&lt;br /&gt;
abstract class of its own, like we did in the example above. We could&lt;br /&gt;
just as well have defined a k_dcop section directly within MyClass:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to skeletons, dcopidl2cpp also generate stubs. Those make&lt;br /&gt;
it easy to call a DCOP interface without doing the marshalling&lt;br /&gt;
manually. To use a stub, add {{path|MyInterface.stub}} to the SOURCES list of&lt;br /&gt;
your {{path|Makefile.am}}. The stub class will then be called MyInterface_stub.&lt;br /&gt;
&lt;br /&gt;
=== Inter-user communication ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it might be interesting to use DCOP between processes&lt;br /&gt;
belonging to different users, e.g. a frontend process running&lt;br /&gt;
with the user's id, and a backend process running as root.&lt;br /&gt;
&lt;br /&gt;
To do this, two steps have to be taken:&lt;br /&gt;
* both processes need to talk to the same DCOP server&lt;br /&gt;
* proper authentication must be ensured&lt;br /&gt;
&lt;br /&gt;
For the first step, you simply pass the server address (as&lt;br /&gt;
found in .DCOPserver) to the second process. For the authentication,&lt;br /&gt;
you can use the ICEAUTHORITY environment variable to tell the&lt;br /&gt;
second process where to find the authentication information.&lt;br /&gt;
(Note that this implies that the second process is able to&lt;br /&gt;
read the authentication file, so it will probably only work&lt;br /&gt;
if the second process runs as root. If it should run as another&lt;br /&gt;
user, a similar approach to what kdesu does with xauth must&lt;br /&gt;
be taken. In fact, it would be a very good idea to add DCOP&lt;br /&gt;
support to kdesu!)&lt;br /&gt;
&lt;br /&gt;
For example&lt;br /&gt;
 ICEAUTHORITY=~user/.ICEauthority kdesu root -c kcmroot -dcopserver `cat ~user/.DCOPserver`&lt;br /&gt;
&lt;br /&gt;
will, after kdesu got the root password, execute kcmroot as root, talking&lt;br /&gt;
to the user's dcop server.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' DCOP communication is not encrypted, so please do not&lt;br /&gt;
pass important information around this way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Performance Tests ==&lt;br /&gt;
&lt;br /&gt;
A few back-of-the-napkin tests folks:&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#include &amp;amp;lt;kapp.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    KApplication *app;&lt;br /&gt;
&lt;br /&gt;
    app = new KApplication(argc, argv, &amp;quot;testit&amp;quot;);&lt;br /&gt;
    return app-&amp;amp;gt;exec();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compiled with:&lt;br /&gt;
 g++ -O2 -o testit testit.cpp -I$QTDIR/include -L$QTDIR/lib -lkdecore&lt;br /&gt;
&lt;br /&gt;
on Linux yields the following memory use statistics:&lt;br /&gt;
 VmSize:     8076 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4532 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
If I create the KApplication's DCOPClient, and call attach() and&lt;br /&gt;
registerAs(), it changes to this:&lt;br /&gt;
 VmSize:     8080 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4624 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
Basically it appears that using DCOP causes 100k more memory to be&lt;br /&gt;
resident, but no more data or stack.  So this will be shared between all&lt;br /&gt;
processes, right?  100k to enable DCOP in all apps doesn't seem bad at&lt;br /&gt;
all. :)&lt;br /&gt;
&lt;br /&gt;
OK now for some timings.  Just creating a KApplication and then exiting&lt;br /&gt;
(i.e. removing the call to KApplication::exec) takes this much time:&lt;br /&gt;
&lt;br /&gt;
 0.28user 0.02system 0:00.32elapsed 92%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1084major+62minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second on my PII-233.  Now, if we create our DCOP&lt;br /&gt;
object and attach to the server, it takes this long:&lt;br /&gt;
&lt;br /&gt;
 0.27user 0.03system 0:00.34elapsed 87%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1107major+65minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second.  Basically DCOPClient creation and attaching&lt;br /&gt;
gets lost in the statistical variation (&amp;quot;noise&amp;quot;).  I was getting times&lt;br /&gt;
between .32 and .48 over several runs for both of the example programs, so&lt;br /&gt;
obviously system load is more relevant than the extra two calls to&lt;br /&gt;
DCOPClient::attach and DCOPClient::registerAs, as well as the actual&lt;br /&gt;
DCOPClient constructor time.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Hopefully this document will get you well on your way into the world&lt;br /&gt;
of inter-process communication with KDE! Please direct all comments&lt;br /&gt;
and/or suggestions to [mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] and [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;].&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE3]]&lt;br /&gt;
[[Category:Architecture]]&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/DCOP</id>
		<title>Development/Architecture/DCOP</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/DCOP"/>
				<updated>2010-05-22T22:09:47Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Receiving Data via DCOP */ replace entities&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;border: 1px solid #2090ff; padding: 1em 1em 1em 1em; background-color:#f8f8ff; align:center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DCOP: Desktop COmmunications Protocol'''&lt;br /&gt;
&lt;br /&gt;
[mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] October 14, 1999&lt;br /&gt;
&lt;br /&gt;
Revised and extended by [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;] Mar 29, 2000&lt;br /&gt;
&lt;br /&gt;
HTMLized by Hans Meine [mailto:rastajoe@gmx.net Hans Meine &amp;amp;lt;rastajoe@gmx.net&amp;amp;gt;] May 25, 2000&lt;br /&gt;
&lt;br /&gt;
Added a DCOPRef example: Tim Jansen May 12, 2003&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Demotivation and Background ==&lt;br /&gt;
&lt;br /&gt;
'''Note that new features may not be developed for DCOP. The successor for DCOP is D-Bus'''&lt;br /&gt;
&lt;br /&gt;
The motivation behind building a protocol like DCOP is simple.  For&lt;br /&gt;
the past year, we have been attempting to enable interprocess&lt;br /&gt;
communication between KDE applications. KDE already has an extremely&lt;br /&gt;
simple IPC mechanism called KWMcom, which is (was!) used for communicating&lt;br /&gt;
between the panel and the window manager for instance.  It is about as&lt;br /&gt;
simple as it gets, passing messages via X Atoms.  For this reason it&lt;br /&gt;
is limited in the size and complexity of the data that can be passed&lt;br /&gt;
(X atoms must be small to remain efficient) and it also makes it so&lt;br /&gt;
that X is required.  CORBA was thought to be a more effective IPC/RPC&lt;br /&gt;
solution.  However, after a year of attempting to make heavy use of&lt;br /&gt;
CORBA in KDE, we have realized that it is a bit slow and memory&lt;br /&gt;
intensive for simple use.  It also has no authentication available.&lt;br /&gt;
&lt;br /&gt;
What we really needed was an extremely simple protocol with basic&lt;br /&gt;
authorization, along the lines of MIT-MAGIC-COOKIE, as used by X.  It&lt;br /&gt;
would not be able to do NEARLY what CORBA was able to do, but for the&lt;br /&gt;
simple tasks required it would be sufficient. Some examples of such&lt;br /&gt;
tasks might be an application sending a message to the panel saying,&lt;br /&gt;
&amp;quot;I have started, stop displaying the 'application starting' wait&lt;br /&gt;
state,&amp;quot; or having a new application that starts query to see if any&lt;br /&gt;
other applications of the same name are running.  If they are, simply&lt;br /&gt;
call a function on the remote application to create a new window,&lt;br /&gt;
rather than starting a new process.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
DCOP is a simple IPC/RPC mechanism built to operate over sockets.&lt;br /&gt;
Either unix domain sockets or tcp/ip sockets are supported. DCOP is&lt;br /&gt;
built on top of the Inter Client Exchange (ICE) protocol, which comes&lt;br /&gt;
standard as a part of X11R6 and later. It also depends on Qt, but&lt;br /&gt;
beyond that it does not require any other libraries. Because of this,&lt;br /&gt;
it is extremely lightweight, enabling it to be linked into all KDE&lt;br /&gt;
applications with low overhead.&lt;br /&gt;
&lt;br /&gt;
=== Model ===&lt;br /&gt;
&lt;br /&gt;
The model is simple.  Each application using DCOP is a client.  They&lt;br /&gt;
communicate to each other through a DCOP server, which functions like&lt;br /&gt;
a traffic director, dispatching messages/calls to the proper&lt;br /&gt;
destinations.  All clients are peers of each other.&lt;br /&gt;
&lt;br /&gt;
Two types of actions are possible with DCOP: &amp;quot;send and forget&amp;quot;&lt;br /&gt;
messages, which do not block, and &amp;quot;calls,&amp;quot; which block waiting for&lt;br /&gt;
some data to be returned.&lt;br /&gt;
&lt;br /&gt;
Any data that will be sent is serialized (marshalled, for you CORBA&lt;br /&gt;
fellows) using the built-in {{qt3|QDataStream}} operators available in all of&lt;br /&gt;
the Qt classes.  This is fast and easy.  In fact it's so little work&lt;br /&gt;
that you can easily write the marshalling code by hand. In addition,&lt;br /&gt;
there's a simple IDL-like compiler available (dcopidl and dcopidl2cpp)&lt;br /&gt;
that generates stubs and skeletons for you. Using the dcopidl compiler&lt;br /&gt;
has the additional benefit of type safety.&lt;br /&gt;
&lt;br /&gt;
This HOWTO describes the manual method first and covers the dcopidl&lt;br /&gt;
compiler later.&lt;br /&gt;
&lt;br /&gt;
=== Managing DCOP Connections Manually ===&lt;br /&gt;
&lt;br /&gt;
==== Establishing the Connection ====&lt;br /&gt;
&lt;br /&gt;
{{class|KApplication|kdelibs|3.5}} has gained a method called &amp;quot;KApplication::dcopClient()&amp;quot;&lt;br /&gt;
which returns a pointer to a DCOPClient instance.  The first time this&lt;br /&gt;
method is called, the client class will be created.  {{class|DCOPClient|kdelibs|3.5}}s have&lt;br /&gt;
unique identifiers attached to them which are based on what&lt;br /&gt;
KApplication::name() returns.  In fact, if there is only a single&lt;br /&gt;
instance of the program running, the appId will be equal to&lt;br /&gt;
KApplication::name().&lt;br /&gt;
&lt;br /&gt;
To actually enable DCOP communication to begin, you must use&lt;br /&gt;
DCOPClient::attach().  This will attempt to attach to the DCOP server.&lt;br /&gt;
If no server is found or there is any other type of error, attach()&lt;br /&gt;
will return false. KApplication will catch a dcop signal and display an&lt;br /&gt;
appropriate error message box in that case.&lt;br /&gt;
&lt;br /&gt;
After connecting with the server via DCOPClient::attach(), you need to&lt;br /&gt;
register this appId with the server so it knows about you.  Otherwise,&lt;br /&gt;
you are communicating anonymously.  Use the&lt;br /&gt;
DCOPClient::registerAs(const QCString &amp;amp;amp;name) to do so.  In the simple&lt;br /&gt;
case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * returns the appId that is actually registered, which _may_ be&lt;br /&gt;
 * different from what you passed&lt;br /&gt;
 */&lt;br /&gt;
appId = client -&amp;gt; registerAs (kApp -&amp;gt; name());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you never retrieve the DCOPClient pointer from KApplication, the&lt;br /&gt;
object will not be created and thus there will be no memory overhead.&lt;br /&gt;
&lt;br /&gt;
You may also detach from the server by calling DCOPClient::detach().&lt;br /&gt;
If you wish to attach again you will need to re-register as well.  If&lt;br /&gt;
you only wish to change the ID under which you are registered, simply&lt;br /&gt;
call DCOPClient::registerAs() with the new name.&lt;br /&gt;
&lt;br /&gt;
KUniqueApplication automatically registers itself to DCOP. If you&lt;br /&gt;
are using KUniqueApplication you should not attach or register&lt;br /&gt;
yourself, this is already done. The appId is by definition&lt;br /&gt;
equal to kapp-&amp;amp;gt;name(). You can retrieve the registered DCOP client&lt;br /&gt;
by calling kapp-&amp;amp;gt;dcopClient().&lt;br /&gt;
&lt;br /&gt;
==== Sending Data to a Remote Application ====&lt;br /&gt;
&lt;br /&gt;
To actually communicate, you have one of two choices.  You may either&lt;br /&gt;
call the &amp;quot;send&amp;quot; or the &amp;quot;call&amp;quot; method.  Both methods require three&lt;br /&gt;
identification parameters: an application identifier, a remote object,&lt;br /&gt;
a remote function. Sending is asynchronous (i.e. it returns immediately)&lt;br /&gt;
and may or may not result in your own application being sent a message at&lt;br /&gt;
some point in the future. Then &amp;quot;send&amp;quot; requires one and &amp;quot;call&amp;quot; requires&lt;br /&gt;
two data parameters.&lt;br /&gt;
&lt;br /&gt;
The remote object must be specified as an object hierarchy.  That is,&lt;br /&gt;
if the toplevel object is called &amp;quot;fooObject&amp;quot; and has the child&lt;br /&gt;
&amp;quot;barObject&amp;quot;, you would reference this object as &amp;quot;fooObject/barObject&amp;quot;.&lt;br /&gt;
Functions must be described by a full function signature.  If the&lt;br /&gt;
remote function is called &amp;quot;doIt&amp;quot;, and it takes an int, it would be&lt;br /&gt;
described as &amp;quot;doIt(int)&amp;quot;.  Please note that the return type is not&lt;br /&gt;
specified here, as it is not part of the function signature (or at&lt;br /&gt;
least the C++ understanding of a function signature).  You will get&lt;br /&gt;
the return type of a function back as an extra parameter to&lt;br /&gt;
DCOPClient::call().  See the section on call() for more details.&lt;br /&gt;
&lt;br /&gt;
In order to actually get the data to the remote client, it must be&lt;br /&gt;
&amp;quot;serialized&amp;quot; via a {{qt3|QDataStream}} operating on a {{qt3|QByteArray}}. This is how&lt;br /&gt;
the data parameter is &amp;quot;built&amp;quot;. A few examples will make clear how this&lt;br /&gt;
works.&lt;br /&gt;
&lt;br /&gt;
Say you want to call &amp;quot;doIt&amp;quot; as described above, and not block (or wait&lt;br /&gt;
for a response).  You will not receive the return value of the remotely&lt;br /&gt;
called function, but you will not hang while the RPC is processed either.&lt;br /&gt;
The return value of send() indicates whether DCOP communication succeeded&lt;br /&gt;
or not.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data;&lt;br /&gt;
QDataStream arg(data, IO_WriteOnly);&lt;br /&gt;
arg &amp;lt;&amp;lt; 5;&lt;br /&gt;
if (!client -&amp;gt; send (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data))&lt;br /&gt;
    qDebug (&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OK, now let's say we wanted to get the data back from the remotely&lt;br /&gt;
called function.  You have to execute a call() instead of a send().&lt;br /&gt;
The returned value will then be available in the data parameter &amp;quot;reply&amp;quot;.&lt;br /&gt;
The actual return value of call() is still whether or not DCOP&lt;br /&gt;
communication was successful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data, replyData;&lt;br /&gt;
QCString replyType;&lt;br /&gt;
QDataStream arg (data, IO_WriteOnly);&lt;br /&gt;
arg &amp;lt;&amp;lt; 5;&lt;br /&gt;
if (!client -&amp;gt; call (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data, replyType, replyData))&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    QDataStream reply (replyData, IO_ReadOnly);&lt;br /&gt;
    if (replyType == &amp;quot;QString&amp;quot;) {&lt;br /&gt;
        QString result;&lt;br /&gt;
        reply &amp;gt;&amp;gt; result;&lt;br /&gt;
        print (&amp;quot;the result is: %s&amp;quot;, result. latin1());&lt;br /&gt;
    } else&lt;br /&gt;
        qDebug (&amp;quot;doIt returned an unexpected type of reply!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''N.B.:'' You cannot call() a method belonging to an application which has&lt;br /&gt;
registered with an unique numeric id appended to its textual name (see&lt;br /&gt;
dcopclient.h for more info). In this case, DCOP would not know which&lt;br /&gt;
application it should connect with to call the method. This is not an issue&lt;br /&gt;
with send(), as you can broadcast to all applications that have registered&lt;br /&gt;
with appname-&amp;amp;lt;numeric_id&amp;amp;gt; by using a wildcard (e.g. 'konsole-*'), which&lt;br /&gt;
will send your signal to all applications called 'konsole'.&lt;br /&gt;
&lt;br /&gt;
Since KDE 3.1 there is an even easier way to make a DCOP call:&lt;br /&gt;
{{class|DCOPRef|kdelibs|3.5}}. Then you only need to create a DCOPRef to the object&lt;br /&gt;
and as long as the function does not use unusual argument types,&lt;br /&gt;
calling the function is as easy as this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
DCOPRef barObject (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;);&lt;br /&gt;
DCOPReply reply = barObject. call (&amp;quot;doIt&amp;quot;, 5);&lt;br /&gt;
if (!reply. isValid())&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    print(&amp;quot;the result is: %s&amp;quot;, ((QString)reply). latin1());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Receiving Data via DCOP ====&lt;br /&gt;
&lt;br /&gt;
Currently the only real way to receive data from DCOP is to multiply&lt;br /&gt;
inherit from the normal class that you are inheriting (usually some&lt;br /&gt;
sort of QWidget subclass or QObject) as well as the DCOPObject class.&lt;br /&gt;
DCOPObject provides one very important method: DCOPObject::process().&lt;br /&gt;
This is a pure virtual method that you must implement in order to&lt;br /&gt;
process DCOP messages that you receive.  It takes a function&lt;br /&gt;
signature, QByteArray of parameters, and a reference to a QByteArray&lt;br /&gt;
for the reply data that you must fill in.&lt;br /&gt;
&lt;br /&gt;
Think of DCOPObject::process() as a sort of dispatch agent.  In the&lt;br /&gt;
future, there will probably be a precompiler for your sources to write&lt;br /&gt;
this method for you.  However, until that point you need to examine&lt;br /&gt;
the incoming function signature and take action accordingly.  Here is&lt;br /&gt;
an example implementation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject:: process (const QCString &amp;amp;fun, const QByteArray &amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;replyType, QByteArray &amp;amp;replyData)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg (data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;gt;&amp;gt; i;&lt;br /&gt;
        QString result = self -&amp;gt; doIt (i);&lt;br /&gt;
        QDataStream reply (replyData, IO_WriteOnly);&lt;br /&gt;
        reply &amp;lt;&amp;lt; result;&lt;br /&gt;
        replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug (&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Processing Received Calls with Transactions ====&lt;br /&gt;
&lt;br /&gt;
If your applications is able to process incoming function calls&lt;br /&gt;
right away the above code is all you need. When your application&lt;br /&gt;
needs to do more complex tasks you might want to do the processing&lt;br /&gt;
out of 'process' function call and send the result back later when&lt;br /&gt;
it becomes available.&lt;br /&gt;
&lt;br /&gt;
For this you can ask your DCOPClient for a transactionId. You can&lt;br /&gt;
then return from the 'process' function and when the result is&lt;br /&gt;
available finish the transaction. In the mean time your application&lt;br /&gt;
can receive incoming DCOP function calls from other clients.&lt;br /&gt;
&lt;br /&gt;
Such code could like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject::process(const QCString &amp;amp;amp;fun, const QByteArray &amp;amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;amp;, QByteArray &amp;amp;amp;)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg(data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;amp;gt;&amp;amp;gt; i;&lt;br /&gt;
        QString result = self-&amp;amp;gt;doIt(i);&lt;br /&gt;
&lt;br /&gt;
        DCOPClientTransaction *myTransaction;&lt;br /&gt;
        myTransaction = kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;beginTransaction();&lt;br /&gt;
&lt;br /&gt;
        // start processing...&lt;br /&gt;
        // Calls slotProcessingDone when finished.&lt;br /&gt;
        startProcessing( myTransaction, i);&lt;br /&gt;
&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug(&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
slotProcessingDone(DCOPClientTransaction *myTransaction, const QString &amp;amp;amp;result)&lt;br /&gt;
{&lt;br /&gt;
    QCString replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
    QByteArray replyData;&lt;br /&gt;
    QDataStream reply(replyData, IO_WriteOnly);&lt;br /&gt;
    reply &amp;amp;lt;&amp;amp;lt; result;&lt;br /&gt;
    kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;endTransaction(myTransaction, replyType, replyData);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DCOP Signals ====&lt;br /&gt;
&lt;br /&gt;
Sometimes a component wants to send notifications via DCOP to other&lt;br /&gt;
components but does not know which components will be interested in these&lt;br /&gt;
notifications. One could use a broadcast in such a case but this is a very&lt;br /&gt;
crude method. For a more sophisticated method DCOP signals have been invented.&lt;br /&gt;
&lt;br /&gt;
DCOP signals are very similair to Qt signals, there are some differences &lt;br /&gt;
though. A DCOP signal can be connected to a DCOP function. Whenever the DCOP&lt;br /&gt;
signal gets emitted, the DCOP functions to which the signal is connected are&lt;br /&gt;
being called. DCOP signals are, just like Qt signals, one way. They do not&lt;br /&gt;
provide a return value. &lt;br /&gt;
&lt;br /&gt;
A DCOP signal originates from a DCOP Object/DCOP Client combination (sender). &lt;br /&gt;
It can be connected to a function of another DCOP Object/DCOP Client &lt;br /&gt;
combination (receiver).&lt;br /&gt;
&lt;br /&gt;
There are two major differences between connections of Qt signals and&lt;br /&gt;
connections of DCOP signals. In DCOP, unlike Qt, a signal connections can&lt;br /&gt;
have an anonymous sender and, unlike Qt, a DCOP signal connection can be&lt;br /&gt;
non-volatile.&lt;br /&gt;
&lt;br /&gt;
With DCOP one can connect a signal without specifying the sending DCOP Object &lt;br /&gt;
or DCOP Client. In that case signals from any DCOP Object and/or DCOP Client&lt;br /&gt;
will be delivered. This allows the specification of certain events without&lt;br /&gt;
tying oneself to a certain object that implementes the events.&lt;br /&gt;
&lt;br /&gt;
Another DCOP feature are so called non-volatile connections. With Qt signal&lt;br /&gt;
connections, the connection gets deleted when either sender or receiver of&lt;br /&gt;
the signal gets deleted. A volatile DCOP signal connection will behave the&lt;br /&gt;
same. However, a non-volatile DCOP signal connection will not get deleted &lt;br /&gt;
when the sending object gets deleted. Once a new object gets created with &lt;br /&gt;
the same name as the original sending object, the connection will be restored.&lt;br /&gt;
There is no difference between the two when the receiving object gets deleted,&lt;br /&gt;
in that case the signal connection will always be deleted.&lt;br /&gt;
&lt;br /&gt;
A receiver can create a non-volatile connection while the sender doesn't (yet)&lt;br /&gt;
exist. An anonymous DCOP connection should always be non-volatile.&lt;br /&gt;
&lt;br /&gt;
The following example shows how KLauncher emits a signal whenever it notices&lt;br /&gt;
that an application that was started via KLauncher terminates.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray params;&lt;br /&gt;
QDataStream stream(params, IO_WriteOnly);&lt;br /&gt;
stream &amp;amp;lt;&amp;amp;lt; pid;&lt;br /&gt;
kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;emitDCOPSignal(&amp;quot;clientDied(pid_t)&amp;quot;, params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The task manager of the KDE panel connects to this signal. It uses an &lt;br /&gt;
anonymous connection (it doesn't require that the signal is being emitted&lt;br /&gt;
by KLauncher) that is non-volatile:&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
connectDCOPSignal(0, 0, &amp;quot;clientDied(pid_t)&amp;quot;, &amp;quot;clientDied(pid_t)&amp;quot;, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It connects the clientDied(pid_t) signal to its own clientDied(pid_t) DCOP&lt;br /&gt;
function. In this case the signal and the function to call have the same name.&lt;br /&gt;
This isn't needed as long as the arguments of both signal and receiving function&lt;br /&gt;
match. The receiving function may ignore one or more of the trailing arguments&lt;br /&gt;
of the signal. E.g. it is allowed to connect the clientDied(pid_t) signal to&lt;br /&gt;
a clientDied(void) DCOP function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the dcopidl compiler ===&lt;br /&gt;
&lt;br /&gt;
dcopidl makes setting up a DCOP server easy. Instead of having to implement&lt;br /&gt;
the process() method and unmarshalling (retrieving from QByteArray) parameters&lt;br /&gt;
manually, you can let dcopidl create the necessary code on your behalf.&lt;br /&gt;
&lt;br /&gt;
This also allows you to describe the interface for your class in a&lt;br /&gt;
single, separate header file.&lt;br /&gt;
&lt;br /&gt;
Writing an IDL file is very similar to writing a normal C++ header. An&lt;br /&gt;
exception is the keyword 'ASYNC'. It indicates that a call to this&lt;br /&gt;
function shall be processed asynchronously. For the C++ compiler, it&lt;br /&gt;
expands to 'void'.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#ifndef MY_INTERFACE_H&lt;br /&gt;
#define MY_INTERFACE_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;amp;lt;dcopobject.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
class MyInterface : virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
&lt;br /&gt;
        virtual ASYNC myAsynchronousMethod(QString someParameter) = 0;&lt;br /&gt;
        virtual QRect mySynchronousMethod() = 0;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, you're essentially declaring an abstract base class, which&lt;br /&gt;
virtually inherits from DCOPObject.&lt;br /&gt;
&lt;br /&gt;
If you're using the standard KDE build scripts, then you can simply add this file (which you would call {{path|MyInterface.h}}) to your sources directory. Then you edit your {{path|Makefile.am}}, adding 'MyInterface.skel' to your SOURCES list and {{path|MyInterface.h}} to include_HEADERS.&lt;br /&gt;
&lt;br /&gt;
The build scripts will use dcopidl to parse {{path|MyInterface.h}}, converting it to an XML description in {{path|MyInterface.kidl}}. Next, a file called {{path|MyInterface_skel.cpp}} will automatically be created, compiled and linked with your binary.&lt;br /&gt;
&lt;br /&gt;
The next thing you have to do is to choose which of your classes will implement the interface described in {{path|MyInterface.h}}. Alter the inheritance of this class such that it virtually inherits from {{path|MyInterface}}. Then add declarations to your class interface similar to those on {{path|MyInterface.h}}, but virtual, not pure virtual.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public MyInterface&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: (Qt issue) Remember that if you are inheriting from {{qt3|QObject}}, you must place it first in the list of inherited classes.&lt;br /&gt;
&lt;br /&gt;
In the implementation of your class' ctor, you must explicitly initialize&lt;br /&gt;
those classes from which you are inheriting from. This is, of course, good&lt;br /&gt;
practise, but it is essential here as you need to tell DCOPObject the name of&lt;br /&gt;
the interface which your are implementing.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
MyClass::MyClass()&lt;br /&gt;
  : QObject(),&lt;br /&gt;
    DCOPObject(&amp;quot;MyInterface&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
    // whatever...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can simply implement the methods you have declared in your interface,&lt;br /&gt;
exactly the same as you would normally.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
void MyClass::myAsynchronousMethod(QString someParameter)&lt;br /&gt;
{&lt;br /&gt;
    qDebug(&amp;quot;myAsyncMethod called with param `&amp;quot; + someParameter + &amp;quot;'&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is not necessary (though very clean) to define an interface as an&lt;br /&gt;
abstract class of its own, like we did in the example above. We could&lt;br /&gt;
just as well have defined a k_dcop section directly within MyClass:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to skeletons, dcopidl2cpp also generate stubs. Those make&lt;br /&gt;
it easy to call a DCOP interface without doing the marshalling&lt;br /&gt;
manually. To use a stub, add {{path|MyInterface.stub}} to the SOURCES list of&lt;br /&gt;
your {{path|Makefile.am}}. The stub class will then be called MyInterface_stub.&lt;br /&gt;
&lt;br /&gt;
=== Inter-user communication ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it might be interesting to use DCOP between processes&lt;br /&gt;
belonging to different users, e.g. a frontend process running&lt;br /&gt;
with the user's id, and a backend process running as root.&lt;br /&gt;
&lt;br /&gt;
To do this, two steps have to be taken:&lt;br /&gt;
* both processes need to talk to the same DCOP server&lt;br /&gt;
* proper authentication must be ensured&lt;br /&gt;
&lt;br /&gt;
For the first step, you simply pass the server address (as&lt;br /&gt;
found in .DCOPserver) to the second process. For the authentication,&lt;br /&gt;
you can use the ICEAUTHORITY environment variable to tell the&lt;br /&gt;
second process where to find the authentication information.&lt;br /&gt;
(Note that this implies that the second process is able to&lt;br /&gt;
read the authentication file, so it will probably only work&lt;br /&gt;
if the second process runs as root. If it should run as another&lt;br /&gt;
user, a similar approach to what kdesu does with xauth must&lt;br /&gt;
be taken. In fact, it would be a very good idea to add DCOP&lt;br /&gt;
support to kdesu!)&lt;br /&gt;
&lt;br /&gt;
For example&lt;br /&gt;
 ICEAUTHORITY=~user/.ICEauthority kdesu root -c kcmroot -dcopserver `cat ~user/.DCOPserver`&lt;br /&gt;
&lt;br /&gt;
will, after kdesu got the root password, execute kcmroot as root, talking&lt;br /&gt;
to the user's dcop server.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' DCOP communication is not encrypted, so please do not&lt;br /&gt;
pass important information around this way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Performance Tests ==&lt;br /&gt;
&lt;br /&gt;
A few back-of-the-napkin tests folks:&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#include &amp;amp;lt;kapp.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    KApplication *app;&lt;br /&gt;
&lt;br /&gt;
    app = new KApplication(argc, argv, &amp;quot;testit&amp;quot;);&lt;br /&gt;
    return app-&amp;amp;gt;exec();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compiled with:&lt;br /&gt;
 g++ -O2 -o testit testit.cpp -I$QTDIR/include -L$QTDIR/lib -lkdecore&lt;br /&gt;
&lt;br /&gt;
on Linux yields the following memory use statistics:&lt;br /&gt;
 VmSize:     8076 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4532 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
If I create the KApplication's DCOPClient, and call attach() and&lt;br /&gt;
registerAs(), it changes to this:&lt;br /&gt;
 VmSize:     8080 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4624 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
Basically it appears that using DCOP causes 100k more memory to be&lt;br /&gt;
resident, but no more data or stack.  So this will be shared between all&lt;br /&gt;
processes, right?  100k to enable DCOP in all apps doesn't seem bad at&lt;br /&gt;
all. :)&lt;br /&gt;
&lt;br /&gt;
OK now for some timings.  Just creating a KApplication and then exiting&lt;br /&gt;
(i.e. removing the call to KApplication::exec) takes this much time:&lt;br /&gt;
&lt;br /&gt;
 0.28user 0.02system 0:00.32elapsed 92%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1084major+62minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second on my PII-233.  Now, if we create our DCOP&lt;br /&gt;
object and attach to the server, it takes this long:&lt;br /&gt;
&lt;br /&gt;
 0.27user 0.03system 0:00.34elapsed 87%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1107major+65minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second.  Basically DCOPClient creation and attaching&lt;br /&gt;
gets lost in the statistical variation (&amp;quot;noise&amp;quot;).  I was getting times&lt;br /&gt;
between .32 and .48 over several runs for both of the example programs, so&lt;br /&gt;
obviously system load is more relevant than the extra two calls to&lt;br /&gt;
DCOPClient::attach and DCOPClient::registerAs, as well as the actual&lt;br /&gt;
DCOPClient constructor time.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Hopefully this document will get you well on your way into the world&lt;br /&gt;
of inter-process communication with KDE! Please direct all comments&lt;br /&gt;
and/or suggestions to [mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] and [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;].&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE3]]&lt;br /&gt;
[[Category:Architecture]]&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/DCOP</id>
		<title>Development/Architecture/DCOP</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/DCOP"/>
				<updated>2010-05-22T22:07:58Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Sending Data to a Remote Application */ replace entities&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;border: 1px solid #2090ff; padding: 1em 1em 1em 1em; background-color:#f8f8ff; align:center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DCOP: Desktop COmmunications Protocol'''&lt;br /&gt;
&lt;br /&gt;
[mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] October 14, 1999&lt;br /&gt;
&lt;br /&gt;
Revised and extended by [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;] Mar 29, 2000&lt;br /&gt;
&lt;br /&gt;
HTMLized by Hans Meine [mailto:rastajoe@gmx.net Hans Meine &amp;amp;lt;rastajoe@gmx.net&amp;amp;gt;] May 25, 2000&lt;br /&gt;
&lt;br /&gt;
Added a DCOPRef example: Tim Jansen May 12, 2003&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Demotivation and Background ==&lt;br /&gt;
&lt;br /&gt;
'''Note that new features may not be developed for DCOP. The successor for DCOP is D-Bus'''&lt;br /&gt;
&lt;br /&gt;
The motivation behind building a protocol like DCOP is simple.  For&lt;br /&gt;
the past year, we have been attempting to enable interprocess&lt;br /&gt;
communication between KDE applications. KDE already has an extremely&lt;br /&gt;
simple IPC mechanism called KWMcom, which is (was!) used for communicating&lt;br /&gt;
between the panel and the window manager for instance.  It is about as&lt;br /&gt;
simple as it gets, passing messages via X Atoms.  For this reason it&lt;br /&gt;
is limited in the size and complexity of the data that can be passed&lt;br /&gt;
(X atoms must be small to remain efficient) and it also makes it so&lt;br /&gt;
that X is required.  CORBA was thought to be a more effective IPC/RPC&lt;br /&gt;
solution.  However, after a year of attempting to make heavy use of&lt;br /&gt;
CORBA in KDE, we have realized that it is a bit slow and memory&lt;br /&gt;
intensive for simple use.  It also has no authentication available.&lt;br /&gt;
&lt;br /&gt;
What we really needed was an extremely simple protocol with basic&lt;br /&gt;
authorization, along the lines of MIT-MAGIC-COOKIE, as used by X.  It&lt;br /&gt;
would not be able to do NEARLY what CORBA was able to do, but for the&lt;br /&gt;
simple tasks required it would be sufficient. Some examples of such&lt;br /&gt;
tasks might be an application sending a message to the panel saying,&lt;br /&gt;
&amp;quot;I have started, stop displaying the 'application starting' wait&lt;br /&gt;
state,&amp;quot; or having a new application that starts query to see if any&lt;br /&gt;
other applications of the same name are running.  If they are, simply&lt;br /&gt;
call a function on the remote application to create a new window,&lt;br /&gt;
rather than starting a new process.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
DCOP is a simple IPC/RPC mechanism built to operate over sockets.&lt;br /&gt;
Either unix domain sockets or tcp/ip sockets are supported. DCOP is&lt;br /&gt;
built on top of the Inter Client Exchange (ICE) protocol, which comes&lt;br /&gt;
standard as a part of X11R6 and later. It also depends on Qt, but&lt;br /&gt;
beyond that it does not require any other libraries. Because of this,&lt;br /&gt;
it is extremely lightweight, enabling it to be linked into all KDE&lt;br /&gt;
applications with low overhead.&lt;br /&gt;
&lt;br /&gt;
=== Model ===&lt;br /&gt;
&lt;br /&gt;
The model is simple.  Each application using DCOP is a client.  They&lt;br /&gt;
communicate to each other through a DCOP server, which functions like&lt;br /&gt;
a traffic director, dispatching messages/calls to the proper&lt;br /&gt;
destinations.  All clients are peers of each other.&lt;br /&gt;
&lt;br /&gt;
Two types of actions are possible with DCOP: &amp;quot;send and forget&amp;quot;&lt;br /&gt;
messages, which do not block, and &amp;quot;calls,&amp;quot; which block waiting for&lt;br /&gt;
some data to be returned.&lt;br /&gt;
&lt;br /&gt;
Any data that will be sent is serialized (marshalled, for you CORBA&lt;br /&gt;
fellows) using the built-in {{qt3|QDataStream}} operators available in all of&lt;br /&gt;
the Qt classes.  This is fast and easy.  In fact it's so little work&lt;br /&gt;
that you can easily write the marshalling code by hand. In addition,&lt;br /&gt;
there's a simple IDL-like compiler available (dcopidl and dcopidl2cpp)&lt;br /&gt;
that generates stubs and skeletons for you. Using the dcopidl compiler&lt;br /&gt;
has the additional benefit of type safety.&lt;br /&gt;
&lt;br /&gt;
This HOWTO describes the manual method first and covers the dcopidl&lt;br /&gt;
compiler later.&lt;br /&gt;
&lt;br /&gt;
=== Managing DCOP Connections Manually ===&lt;br /&gt;
&lt;br /&gt;
==== Establishing the Connection ====&lt;br /&gt;
&lt;br /&gt;
{{class|KApplication|kdelibs|3.5}} has gained a method called &amp;quot;KApplication::dcopClient()&amp;quot;&lt;br /&gt;
which returns a pointer to a DCOPClient instance.  The first time this&lt;br /&gt;
method is called, the client class will be created.  {{class|DCOPClient|kdelibs|3.5}}s have&lt;br /&gt;
unique identifiers attached to them which are based on what&lt;br /&gt;
KApplication::name() returns.  In fact, if there is only a single&lt;br /&gt;
instance of the program running, the appId will be equal to&lt;br /&gt;
KApplication::name().&lt;br /&gt;
&lt;br /&gt;
To actually enable DCOP communication to begin, you must use&lt;br /&gt;
DCOPClient::attach().  This will attempt to attach to the DCOP server.&lt;br /&gt;
If no server is found or there is any other type of error, attach()&lt;br /&gt;
will return false. KApplication will catch a dcop signal and display an&lt;br /&gt;
appropriate error message box in that case.&lt;br /&gt;
&lt;br /&gt;
After connecting with the server via DCOPClient::attach(), you need to&lt;br /&gt;
register this appId with the server so it knows about you.  Otherwise,&lt;br /&gt;
you are communicating anonymously.  Use the&lt;br /&gt;
DCOPClient::registerAs(const QCString &amp;amp;amp;name) to do so.  In the simple&lt;br /&gt;
case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * returns the appId that is actually registered, which _may_ be&lt;br /&gt;
 * different from what you passed&lt;br /&gt;
 */&lt;br /&gt;
appId = client -&amp;gt; registerAs (kApp -&amp;gt; name());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you never retrieve the DCOPClient pointer from KApplication, the&lt;br /&gt;
object will not be created and thus there will be no memory overhead.&lt;br /&gt;
&lt;br /&gt;
You may also detach from the server by calling DCOPClient::detach().&lt;br /&gt;
If you wish to attach again you will need to re-register as well.  If&lt;br /&gt;
you only wish to change the ID under which you are registered, simply&lt;br /&gt;
call DCOPClient::registerAs() with the new name.&lt;br /&gt;
&lt;br /&gt;
KUniqueApplication automatically registers itself to DCOP. If you&lt;br /&gt;
are using KUniqueApplication you should not attach or register&lt;br /&gt;
yourself, this is already done. The appId is by definition&lt;br /&gt;
equal to kapp-&amp;amp;gt;name(). You can retrieve the registered DCOP client&lt;br /&gt;
by calling kapp-&amp;amp;gt;dcopClient().&lt;br /&gt;
&lt;br /&gt;
==== Sending Data to a Remote Application ====&lt;br /&gt;
&lt;br /&gt;
To actually communicate, you have one of two choices.  You may either&lt;br /&gt;
call the &amp;quot;send&amp;quot; or the &amp;quot;call&amp;quot; method.  Both methods require three&lt;br /&gt;
identification parameters: an application identifier, a remote object,&lt;br /&gt;
a remote function. Sending is asynchronous (i.e. it returns immediately)&lt;br /&gt;
and may or may not result in your own application being sent a message at&lt;br /&gt;
some point in the future. Then &amp;quot;send&amp;quot; requires one and &amp;quot;call&amp;quot; requires&lt;br /&gt;
two data parameters.&lt;br /&gt;
&lt;br /&gt;
The remote object must be specified as an object hierarchy.  That is,&lt;br /&gt;
if the toplevel object is called &amp;quot;fooObject&amp;quot; and has the child&lt;br /&gt;
&amp;quot;barObject&amp;quot;, you would reference this object as &amp;quot;fooObject/barObject&amp;quot;.&lt;br /&gt;
Functions must be described by a full function signature.  If the&lt;br /&gt;
remote function is called &amp;quot;doIt&amp;quot;, and it takes an int, it would be&lt;br /&gt;
described as &amp;quot;doIt(int)&amp;quot;.  Please note that the return type is not&lt;br /&gt;
specified here, as it is not part of the function signature (or at&lt;br /&gt;
least the C++ understanding of a function signature).  You will get&lt;br /&gt;
the return type of a function back as an extra parameter to&lt;br /&gt;
DCOPClient::call().  See the section on call() for more details.&lt;br /&gt;
&lt;br /&gt;
In order to actually get the data to the remote client, it must be&lt;br /&gt;
&amp;quot;serialized&amp;quot; via a {{qt3|QDataStream}} operating on a {{qt3|QByteArray}}. This is how&lt;br /&gt;
the data parameter is &amp;quot;built&amp;quot;. A few examples will make clear how this&lt;br /&gt;
works.&lt;br /&gt;
&lt;br /&gt;
Say you want to call &amp;quot;doIt&amp;quot; as described above, and not block (or wait&lt;br /&gt;
for a response).  You will not receive the return value of the remotely&lt;br /&gt;
called function, but you will not hang while the RPC is processed either.&lt;br /&gt;
The return value of send() indicates whether DCOP communication succeeded&lt;br /&gt;
or not.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data;&lt;br /&gt;
QDataStream arg(data, IO_WriteOnly);&lt;br /&gt;
arg &amp;lt;&amp;lt; 5;&lt;br /&gt;
if (!client -&amp;gt; send (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data))&lt;br /&gt;
    qDebug (&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OK, now let's say we wanted to get the data back from the remotely&lt;br /&gt;
called function.  You have to execute a call() instead of a send().&lt;br /&gt;
The returned value will then be available in the data parameter &amp;quot;reply&amp;quot;.&lt;br /&gt;
The actual return value of call() is still whether or not DCOP&lt;br /&gt;
communication was successful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data, replyData;&lt;br /&gt;
QCString replyType;&lt;br /&gt;
QDataStream arg (data, IO_WriteOnly);&lt;br /&gt;
arg &amp;lt;&amp;lt; 5;&lt;br /&gt;
if (!client -&amp;gt; call (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data, replyType, replyData))&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    QDataStream reply (replyData, IO_ReadOnly);&lt;br /&gt;
    if (replyType == &amp;quot;QString&amp;quot;) {&lt;br /&gt;
        QString result;&lt;br /&gt;
        reply &amp;gt;&amp;gt; result;&lt;br /&gt;
        print (&amp;quot;the result is: %s&amp;quot;, result. latin1());&lt;br /&gt;
    } else&lt;br /&gt;
        qDebug (&amp;quot;doIt returned an unexpected type of reply!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''N.B.:'' You cannot call() a method belonging to an application which has&lt;br /&gt;
registered with an unique numeric id appended to its textual name (see&lt;br /&gt;
dcopclient.h for more info). In this case, DCOP would not know which&lt;br /&gt;
application it should connect with to call the method. This is not an issue&lt;br /&gt;
with send(), as you can broadcast to all applications that have registered&lt;br /&gt;
with appname-&amp;amp;lt;numeric_id&amp;amp;gt; by using a wildcard (e.g. 'konsole-*'), which&lt;br /&gt;
will send your signal to all applications called 'konsole'.&lt;br /&gt;
&lt;br /&gt;
Since KDE 3.1 there is an even easier way to make a DCOP call:&lt;br /&gt;
{{class|DCOPRef|kdelibs|3.5}}. Then you only need to create a DCOPRef to the object&lt;br /&gt;
and as long as the function does not use unusual argument types,&lt;br /&gt;
calling the function is as easy as this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
DCOPRef barObject (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;);&lt;br /&gt;
DCOPReply reply = barObject. call (&amp;quot;doIt&amp;quot;, 5);&lt;br /&gt;
if (!reply. isValid())&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    print(&amp;quot;the result is: %s&amp;quot;, ((QString)reply). latin1());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Receiving Data via DCOP ====&lt;br /&gt;
&lt;br /&gt;
Currently the only real way to receive data from DCOP is to multiply&lt;br /&gt;
inherit from the normal class that you are inheriting (usually some&lt;br /&gt;
sort of QWidget subclass or QObject) as well as the DCOPObject class.&lt;br /&gt;
DCOPObject provides one very important method: DCOPObject::process().&lt;br /&gt;
This is a pure virtual method that you must implement in order to&lt;br /&gt;
process DCOP messages that you receive.  It takes a function&lt;br /&gt;
signature, QByteArray of parameters, and a reference to a QByteArray&lt;br /&gt;
for the reply data that you must fill in.&lt;br /&gt;
&lt;br /&gt;
Think of DCOPObject::process() as a sort of dispatch agent.  In the&lt;br /&gt;
future, there will probably be a precompiler for your sources to write&lt;br /&gt;
this method for you.  However, until that point you need to examine&lt;br /&gt;
the incoming function signature and take action accordingly.  Here is&lt;br /&gt;
an example implementation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject::process(const QCString &amp;amp;amp;fun, const QByteArray &amp;amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;amp;replyType, QByteArray &amp;amp;amp;replyData)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg(data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;amp;gt;&amp;amp;gt; i;&lt;br /&gt;
        QString result = self-&amp;amp;gt;doIt (i);&lt;br /&gt;
        QDataStream reply(replyData, IO_WriteOnly);&lt;br /&gt;
        reply &amp;amp;lt;&amp;amp;lt; result;&lt;br /&gt;
        replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug(&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Processing Received Calls with Transactions ====&lt;br /&gt;
&lt;br /&gt;
If your applications is able to process incoming function calls&lt;br /&gt;
right away the above code is all you need. When your application&lt;br /&gt;
needs to do more complex tasks you might want to do the processing&lt;br /&gt;
out of 'process' function call and send the result back later when&lt;br /&gt;
it becomes available.&lt;br /&gt;
&lt;br /&gt;
For this you can ask your DCOPClient for a transactionId. You can&lt;br /&gt;
then return from the 'process' function and when the result is&lt;br /&gt;
available finish the transaction. In the mean time your application&lt;br /&gt;
can receive incoming DCOP function calls from other clients.&lt;br /&gt;
&lt;br /&gt;
Such code could like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject::process(const QCString &amp;amp;amp;fun, const QByteArray &amp;amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;amp;, QByteArray &amp;amp;amp;)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg(data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;amp;gt;&amp;amp;gt; i;&lt;br /&gt;
        QString result = self-&amp;amp;gt;doIt(i);&lt;br /&gt;
&lt;br /&gt;
        DCOPClientTransaction *myTransaction;&lt;br /&gt;
        myTransaction = kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;beginTransaction();&lt;br /&gt;
&lt;br /&gt;
        // start processing...&lt;br /&gt;
        // Calls slotProcessingDone when finished.&lt;br /&gt;
        startProcessing( myTransaction, i);&lt;br /&gt;
&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug(&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
slotProcessingDone(DCOPClientTransaction *myTransaction, const QString &amp;amp;amp;result)&lt;br /&gt;
{&lt;br /&gt;
    QCString replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
    QByteArray replyData;&lt;br /&gt;
    QDataStream reply(replyData, IO_WriteOnly);&lt;br /&gt;
    reply &amp;amp;lt;&amp;amp;lt; result;&lt;br /&gt;
    kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;endTransaction(myTransaction, replyType, replyData);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DCOP Signals ====&lt;br /&gt;
&lt;br /&gt;
Sometimes a component wants to send notifications via DCOP to other&lt;br /&gt;
components but does not know which components will be interested in these&lt;br /&gt;
notifications. One could use a broadcast in such a case but this is a very&lt;br /&gt;
crude method. For a more sophisticated method DCOP signals have been invented.&lt;br /&gt;
&lt;br /&gt;
DCOP signals are very similair to Qt signals, there are some differences &lt;br /&gt;
though. A DCOP signal can be connected to a DCOP function. Whenever the DCOP&lt;br /&gt;
signal gets emitted, the DCOP functions to which the signal is connected are&lt;br /&gt;
being called. DCOP signals are, just like Qt signals, one way. They do not&lt;br /&gt;
provide a return value. &lt;br /&gt;
&lt;br /&gt;
A DCOP signal originates from a DCOP Object/DCOP Client combination (sender). &lt;br /&gt;
It can be connected to a function of another DCOP Object/DCOP Client &lt;br /&gt;
combination (receiver).&lt;br /&gt;
&lt;br /&gt;
There are two major differences between connections of Qt signals and&lt;br /&gt;
connections of DCOP signals. In DCOP, unlike Qt, a signal connections can&lt;br /&gt;
have an anonymous sender and, unlike Qt, a DCOP signal connection can be&lt;br /&gt;
non-volatile.&lt;br /&gt;
&lt;br /&gt;
With DCOP one can connect a signal without specifying the sending DCOP Object &lt;br /&gt;
or DCOP Client. In that case signals from any DCOP Object and/or DCOP Client&lt;br /&gt;
will be delivered. This allows the specification of certain events without&lt;br /&gt;
tying oneself to a certain object that implementes the events.&lt;br /&gt;
&lt;br /&gt;
Another DCOP feature are so called non-volatile connections. With Qt signal&lt;br /&gt;
connections, the connection gets deleted when either sender or receiver of&lt;br /&gt;
the signal gets deleted. A volatile DCOP signal connection will behave the&lt;br /&gt;
same. However, a non-volatile DCOP signal connection will not get deleted &lt;br /&gt;
when the sending object gets deleted. Once a new object gets created with &lt;br /&gt;
the same name as the original sending object, the connection will be restored.&lt;br /&gt;
There is no difference between the two when the receiving object gets deleted,&lt;br /&gt;
in that case the signal connection will always be deleted.&lt;br /&gt;
&lt;br /&gt;
A receiver can create a non-volatile connection while the sender doesn't (yet)&lt;br /&gt;
exist. An anonymous DCOP connection should always be non-volatile.&lt;br /&gt;
&lt;br /&gt;
The following example shows how KLauncher emits a signal whenever it notices&lt;br /&gt;
that an application that was started via KLauncher terminates.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray params;&lt;br /&gt;
QDataStream stream(params, IO_WriteOnly);&lt;br /&gt;
stream &amp;amp;lt;&amp;amp;lt; pid;&lt;br /&gt;
kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;emitDCOPSignal(&amp;quot;clientDied(pid_t)&amp;quot;, params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The task manager of the KDE panel connects to this signal. It uses an &lt;br /&gt;
anonymous connection (it doesn't require that the signal is being emitted&lt;br /&gt;
by KLauncher) that is non-volatile:&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
connectDCOPSignal(0, 0, &amp;quot;clientDied(pid_t)&amp;quot;, &amp;quot;clientDied(pid_t)&amp;quot;, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It connects the clientDied(pid_t) signal to its own clientDied(pid_t) DCOP&lt;br /&gt;
function. In this case the signal and the function to call have the same name.&lt;br /&gt;
This isn't needed as long as the arguments of both signal and receiving function&lt;br /&gt;
match. The receiving function may ignore one or more of the trailing arguments&lt;br /&gt;
of the signal. E.g. it is allowed to connect the clientDied(pid_t) signal to&lt;br /&gt;
a clientDied(void) DCOP function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the dcopidl compiler ===&lt;br /&gt;
&lt;br /&gt;
dcopidl makes setting up a DCOP server easy. Instead of having to implement&lt;br /&gt;
the process() method and unmarshalling (retrieving from QByteArray) parameters&lt;br /&gt;
manually, you can let dcopidl create the necessary code on your behalf.&lt;br /&gt;
&lt;br /&gt;
This also allows you to describe the interface for your class in a&lt;br /&gt;
single, separate header file.&lt;br /&gt;
&lt;br /&gt;
Writing an IDL file is very similar to writing a normal C++ header. An&lt;br /&gt;
exception is the keyword 'ASYNC'. It indicates that a call to this&lt;br /&gt;
function shall be processed asynchronously. For the C++ compiler, it&lt;br /&gt;
expands to 'void'.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#ifndef MY_INTERFACE_H&lt;br /&gt;
#define MY_INTERFACE_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;amp;lt;dcopobject.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
class MyInterface : virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
&lt;br /&gt;
        virtual ASYNC myAsynchronousMethod(QString someParameter) = 0;&lt;br /&gt;
        virtual QRect mySynchronousMethod() = 0;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, you're essentially declaring an abstract base class, which&lt;br /&gt;
virtually inherits from DCOPObject.&lt;br /&gt;
&lt;br /&gt;
If you're using the standard KDE build scripts, then you can simply add this file (which you would call {{path|MyInterface.h}}) to your sources directory. Then you edit your {{path|Makefile.am}}, adding 'MyInterface.skel' to your SOURCES list and {{path|MyInterface.h}} to include_HEADERS.&lt;br /&gt;
&lt;br /&gt;
The build scripts will use dcopidl to parse {{path|MyInterface.h}}, converting it to an XML description in {{path|MyInterface.kidl}}. Next, a file called {{path|MyInterface_skel.cpp}} will automatically be created, compiled and linked with your binary.&lt;br /&gt;
&lt;br /&gt;
The next thing you have to do is to choose which of your classes will implement the interface described in {{path|MyInterface.h}}. Alter the inheritance of this class such that it virtually inherits from {{path|MyInterface}}. Then add declarations to your class interface similar to those on {{path|MyInterface.h}}, but virtual, not pure virtual.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public MyInterface&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: (Qt issue) Remember that if you are inheriting from {{qt3|QObject}}, you must place it first in the list of inherited classes.&lt;br /&gt;
&lt;br /&gt;
In the implementation of your class' ctor, you must explicitly initialize&lt;br /&gt;
those classes from which you are inheriting from. This is, of course, good&lt;br /&gt;
practise, but it is essential here as you need to tell DCOPObject the name of&lt;br /&gt;
the interface which your are implementing.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
MyClass::MyClass()&lt;br /&gt;
  : QObject(),&lt;br /&gt;
    DCOPObject(&amp;quot;MyInterface&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
    // whatever...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can simply implement the methods you have declared in your interface,&lt;br /&gt;
exactly the same as you would normally.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
void MyClass::myAsynchronousMethod(QString someParameter)&lt;br /&gt;
{&lt;br /&gt;
    qDebug(&amp;quot;myAsyncMethod called with param `&amp;quot; + someParameter + &amp;quot;'&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is not necessary (though very clean) to define an interface as an&lt;br /&gt;
abstract class of its own, like we did in the example above. We could&lt;br /&gt;
just as well have defined a k_dcop section directly within MyClass:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to skeletons, dcopidl2cpp also generate stubs. Those make&lt;br /&gt;
it easy to call a DCOP interface without doing the marshalling&lt;br /&gt;
manually. To use a stub, add {{path|MyInterface.stub}} to the SOURCES list of&lt;br /&gt;
your {{path|Makefile.am}}. The stub class will then be called MyInterface_stub.&lt;br /&gt;
&lt;br /&gt;
=== Inter-user communication ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it might be interesting to use DCOP between processes&lt;br /&gt;
belonging to different users, e.g. a frontend process running&lt;br /&gt;
with the user's id, and a backend process running as root.&lt;br /&gt;
&lt;br /&gt;
To do this, two steps have to be taken:&lt;br /&gt;
* both processes need to talk to the same DCOP server&lt;br /&gt;
* proper authentication must be ensured&lt;br /&gt;
&lt;br /&gt;
For the first step, you simply pass the server address (as&lt;br /&gt;
found in .DCOPserver) to the second process. For the authentication,&lt;br /&gt;
you can use the ICEAUTHORITY environment variable to tell the&lt;br /&gt;
second process where to find the authentication information.&lt;br /&gt;
(Note that this implies that the second process is able to&lt;br /&gt;
read the authentication file, so it will probably only work&lt;br /&gt;
if the second process runs as root. If it should run as another&lt;br /&gt;
user, a similar approach to what kdesu does with xauth must&lt;br /&gt;
be taken. In fact, it would be a very good idea to add DCOP&lt;br /&gt;
support to kdesu!)&lt;br /&gt;
&lt;br /&gt;
For example&lt;br /&gt;
 ICEAUTHORITY=~user/.ICEauthority kdesu root -c kcmroot -dcopserver `cat ~user/.DCOPserver`&lt;br /&gt;
&lt;br /&gt;
will, after kdesu got the root password, execute kcmroot as root, talking&lt;br /&gt;
to the user's dcop server.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' DCOP communication is not encrypted, so please do not&lt;br /&gt;
pass important information around this way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Performance Tests ==&lt;br /&gt;
&lt;br /&gt;
A few back-of-the-napkin tests folks:&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#include &amp;amp;lt;kapp.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    KApplication *app;&lt;br /&gt;
&lt;br /&gt;
    app = new KApplication(argc, argv, &amp;quot;testit&amp;quot;);&lt;br /&gt;
    return app-&amp;amp;gt;exec();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compiled with:&lt;br /&gt;
 g++ -O2 -o testit testit.cpp -I$QTDIR/include -L$QTDIR/lib -lkdecore&lt;br /&gt;
&lt;br /&gt;
on Linux yields the following memory use statistics:&lt;br /&gt;
 VmSize:     8076 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4532 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
If I create the KApplication's DCOPClient, and call attach() and&lt;br /&gt;
registerAs(), it changes to this:&lt;br /&gt;
 VmSize:     8080 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4624 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
Basically it appears that using DCOP causes 100k more memory to be&lt;br /&gt;
resident, but no more data or stack.  So this will be shared between all&lt;br /&gt;
processes, right?  100k to enable DCOP in all apps doesn't seem bad at&lt;br /&gt;
all. :)&lt;br /&gt;
&lt;br /&gt;
OK now for some timings.  Just creating a KApplication and then exiting&lt;br /&gt;
(i.e. removing the call to KApplication::exec) takes this much time:&lt;br /&gt;
&lt;br /&gt;
 0.28user 0.02system 0:00.32elapsed 92%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1084major+62minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second on my PII-233.  Now, if we create our DCOP&lt;br /&gt;
object and attach to the server, it takes this long:&lt;br /&gt;
&lt;br /&gt;
 0.27user 0.03system 0:00.34elapsed 87%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1107major+65minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second.  Basically DCOPClient creation and attaching&lt;br /&gt;
gets lost in the statistical variation (&amp;quot;noise&amp;quot;).  I was getting times&lt;br /&gt;
between .32 and .48 over several runs for both of the example programs, so&lt;br /&gt;
obviously system load is more relevant than the extra two calls to&lt;br /&gt;
DCOPClient::attach and DCOPClient::registerAs, as well as the actual&lt;br /&gt;
DCOPClient constructor time.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Hopefully this document will get you well on your way into the world&lt;br /&gt;
of inter-process communication with KDE! Please direct all comments&lt;br /&gt;
and/or suggestions to [mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] and [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;].&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE3]]&lt;br /&gt;
[[Category:Architecture]]&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/DCOP</id>
		<title>Development/Architecture/DCOP</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/DCOP"/>
				<updated>2010-05-22T22:06:26Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Sending Data to a Remote Application */ replace entities&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;border: 1px solid #2090ff; padding: 1em 1em 1em 1em; background-color:#f8f8ff; align:center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DCOP: Desktop COmmunications Protocol'''&lt;br /&gt;
&lt;br /&gt;
[mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] October 14, 1999&lt;br /&gt;
&lt;br /&gt;
Revised and extended by [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;] Mar 29, 2000&lt;br /&gt;
&lt;br /&gt;
HTMLized by Hans Meine [mailto:rastajoe@gmx.net Hans Meine &amp;amp;lt;rastajoe@gmx.net&amp;amp;gt;] May 25, 2000&lt;br /&gt;
&lt;br /&gt;
Added a DCOPRef example: Tim Jansen May 12, 2003&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Demotivation and Background ==&lt;br /&gt;
&lt;br /&gt;
'''Note that new features may not be developed for DCOP. The successor for DCOP is D-Bus'''&lt;br /&gt;
&lt;br /&gt;
The motivation behind building a protocol like DCOP is simple.  For&lt;br /&gt;
the past year, we have been attempting to enable interprocess&lt;br /&gt;
communication between KDE applications. KDE already has an extremely&lt;br /&gt;
simple IPC mechanism called KWMcom, which is (was!) used for communicating&lt;br /&gt;
between the panel and the window manager for instance.  It is about as&lt;br /&gt;
simple as it gets, passing messages via X Atoms.  For this reason it&lt;br /&gt;
is limited in the size and complexity of the data that can be passed&lt;br /&gt;
(X atoms must be small to remain efficient) and it also makes it so&lt;br /&gt;
that X is required.  CORBA was thought to be a more effective IPC/RPC&lt;br /&gt;
solution.  However, after a year of attempting to make heavy use of&lt;br /&gt;
CORBA in KDE, we have realized that it is a bit slow and memory&lt;br /&gt;
intensive for simple use.  It also has no authentication available.&lt;br /&gt;
&lt;br /&gt;
What we really needed was an extremely simple protocol with basic&lt;br /&gt;
authorization, along the lines of MIT-MAGIC-COOKIE, as used by X.  It&lt;br /&gt;
would not be able to do NEARLY what CORBA was able to do, but for the&lt;br /&gt;
simple tasks required it would be sufficient. Some examples of such&lt;br /&gt;
tasks might be an application sending a message to the panel saying,&lt;br /&gt;
&amp;quot;I have started, stop displaying the 'application starting' wait&lt;br /&gt;
state,&amp;quot; or having a new application that starts query to see if any&lt;br /&gt;
other applications of the same name are running.  If they are, simply&lt;br /&gt;
call a function on the remote application to create a new window,&lt;br /&gt;
rather than starting a new process.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
DCOP is a simple IPC/RPC mechanism built to operate over sockets.&lt;br /&gt;
Either unix domain sockets or tcp/ip sockets are supported. DCOP is&lt;br /&gt;
built on top of the Inter Client Exchange (ICE) protocol, which comes&lt;br /&gt;
standard as a part of X11R6 and later. It also depends on Qt, but&lt;br /&gt;
beyond that it does not require any other libraries. Because of this,&lt;br /&gt;
it is extremely lightweight, enabling it to be linked into all KDE&lt;br /&gt;
applications with low overhead.&lt;br /&gt;
&lt;br /&gt;
=== Model ===&lt;br /&gt;
&lt;br /&gt;
The model is simple.  Each application using DCOP is a client.  They&lt;br /&gt;
communicate to each other through a DCOP server, which functions like&lt;br /&gt;
a traffic director, dispatching messages/calls to the proper&lt;br /&gt;
destinations.  All clients are peers of each other.&lt;br /&gt;
&lt;br /&gt;
Two types of actions are possible with DCOP: &amp;quot;send and forget&amp;quot;&lt;br /&gt;
messages, which do not block, and &amp;quot;calls,&amp;quot; which block waiting for&lt;br /&gt;
some data to be returned.&lt;br /&gt;
&lt;br /&gt;
Any data that will be sent is serialized (marshalled, for you CORBA&lt;br /&gt;
fellows) using the built-in {{qt3|QDataStream}} operators available in all of&lt;br /&gt;
the Qt classes.  This is fast and easy.  In fact it's so little work&lt;br /&gt;
that you can easily write the marshalling code by hand. In addition,&lt;br /&gt;
there's a simple IDL-like compiler available (dcopidl and dcopidl2cpp)&lt;br /&gt;
that generates stubs and skeletons for you. Using the dcopidl compiler&lt;br /&gt;
has the additional benefit of type safety.&lt;br /&gt;
&lt;br /&gt;
This HOWTO describes the manual method first and covers the dcopidl&lt;br /&gt;
compiler later.&lt;br /&gt;
&lt;br /&gt;
=== Managing DCOP Connections Manually ===&lt;br /&gt;
&lt;br /&gt;
==== Establishing the Connection ====&lt;br /&gt;
&lt;br /&gt;
{{class|KApplication|kdelibs|3.5}} has gained a method called &amp;quot;KApplication::dcopClient()&amp;quot;&lt;br /&gt;
which returns a pointer to a DCOPClient instance.  The first time this&lt;br /&gt;
method is called, the client class will be created.  {{class|DCOPClient|kdelibs|3.5}}s have&lt;br /&gt;
unique identifiers attached to them which are based on what&lt;br /&gt;
KApplication::name() returns.  In fact, if there is only a single&lt;br /&gt;
instance of the program running, the appId will be equal to&lt;br /&gt;
KApplication::name().&lt;br /&gt;
&lt;br /&gt;
To actually enable DCOP communication to begin, you must use&lt;br /&gt;
DCOPClient::attach().  This will attempt to attach to the DCOP server.&lt;br /&gt;
If no server is found or there is any other type of error, attach()&lt;br /&gt;
will return false. KApplication will catch a dcop signal and display an&lt;br /&gt;
appropriate error message box in that case.&lt;br /&gt;
&lt;br /&gt;
After connecting with the server via DCOPClient::attach(), you need to&lt;br /&gt;
register this appId with the server so it knows about you.  Otherwise,&lt;br /&gt;
you are communicating anonymously.  Use the&lt;br /&gt;
DCOPClient::registerAs(const QCString &amp;amp;amp;name) to do so.  In the simple&lt;br /&gt;
case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * returns the appId that is actually registered, which _may_ be&lt;br /&gt;
 * different from what you passed&lt;br /&gt;
 */&lt;br /&gt;
appId = client -&amp;gt; registerAs (kApp -&amp;gt; name());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you never retrieve the DCOPClient pointer from KApplication, the&lt;br /&gt;
object will not be created and thus there will be no memory overhead.&lt;br /&gt;
&lt;br /&gt;
You may also detach from the server by calling DCOPClient::detach().&lt;br /&gt;
If you wish to attach again you will need to re-register as well.  If&lt;br /&gt;
you only wish to change the ID under which you are registered, simply&lt;br /&gt;
call DCOPClient::registerAs() with the new name.&lt;br /&gt;
&lt;br /&gt;
KUniqueApplication automatically registers itself to DCOP. If you&lt;br /&gt;
are using KUniqueApplication you should not attach or register&lt;br /&gt;
yourself, this is already done. The appId is by definition&lt;br /&gt;
equal to kapp-&amp;amp;gt;name(). You can retrieve the registered DCOP client&lt;br /&gt;
by calling kapp-&amp;amp;gt;dcopClient().&lt;br /&gt;
&lt;br /&gt;
==== Sending Data to a Remote Application ====&lt;br /&gt;
&lt;br /&gt;
To actually communicate, you have one of two choices.  You may either&lt;br /&gt;
call the &amp;quot;send&amp;quot; or the &amp;quot;call&amp;quot; method.  Both methods require three&lt;br /&gt;
identification parameters: an application identifier, a remote object,&lt;br /&gt;
a remote function. Sending is asynchronous (i.e. it returns immediately)&lt;br /&gt;
and may or may not result in your own application being sent a message at&lt;br /&gt;
some point in the future. Then &amp;quot;send&amp;quot; requires one and &amp;quot;call&amp;quot; requires&lt;br /&gt;
two data parameters.&lt;br /&gt;
&lt;br /&gt;
The remote object must be specified as an object hierarchy.  That is,&lt;br /&gt;
if the toplevel object is called &amp;quot;fooObject&amp;quot; and has the child&lt;br /&gt;
&amp;quot;barObject&amp;quot;, you would reference this object as &amp;quot;fooObject/barObject&amp;quot;.&lt;br /&gt;
Functions must be described by a full function signature.  If the&lt;br /&gt;
remote function is called &amp;quot;doIt&amp;quot;, and it takes an int, it would be&lt;br /&gt;
described as &amp;quot;doIt(int)&amp;quot;.  Please note that the return type is not&lt;br /&gt;
specified here, as it is not part of the function signature (or at&lt;br /&gt;
least the C++ understanding of a function signature).  You will get&lt;br /&gt;
the return type of a function back as an extra parameter to&lt;br /&gt;
DCOPClient::call().  See the section on call() for more details.&lt;br /&gt;
&lt;br /&gt;
In order to actually get the data to the remote client, it must be&lt;br /&gt;
&amp;quot;serialized&amp;quot; via a {{qt3|QDataStream}} operating on a {{qt3|QByteArray}}. This is how&lt;br /&gt;
the data parameter is &amp;quot;built&amp;quot;. A few examples will make clear how this&lt;br /&gt;
works.&lt;br /&gt;
&lt;br /&gt;
Say you want to call &amp;quot;doIt&amp;quot; as described above, and not block (or wait&lt;br /&gt;
for a response).  You will not receive the return value of the remotely&lt;br /&gt;
called function, but you will not hang while the RPC is processed either.&lt;br /&gt;
The return value of send() indicates whether DCOP communication succeeded&lt;br /&gt;
or not.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data;&lt;br /&gt;
QDataStream arg(data, IO_WriteOnly);&lt;br /&gt;
arg &amp;amp;lt;&amp;amp;lt; 5;&lt;br /&gt;
if (!client-&amp;amp;gt;send(&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data))&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OK, now let's say we wanted to get the data back from the remotely&lt;br /&gt;
called function.  You have to execute a call() instead of a send().&lt;br /&gt;
The returned value will then be available in the data parameter &amp;quot;reply&amp;quot;.&lt;br /&gt;
The actual return value of call() is still whether or not DCOP&lt;br /&gt;
communication was successful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data, replyData;&lt;br /&gt;
QCString replyType;&lt;br /&gt;
QDataStream arg (data, IO_WriteOnly);&lt;br /&gt;
arg &amp;lt;&amp;lt; 5;&lt;br /&gt;
if (!client -&amp;gt; call (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data, replyType, replyData))&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    QDataStream reply (replyData, IO_ReadOnly);&lt;br /&gt;
    if (replyType == &amp;quot;QString&amp;quot;) {&lt;br /&gt;
        QString result;&lt;br /&gt;
        reply &amp;gt;&amp;gt; result;&lt;br /&gt;
        print (&amp;quot;the result is: %s&amp;quot;, result. latin1());&lt;br /&gt;
    } else&lt;br /&gt;
        qDebug (&amp;quot;doIt returned an unexpected type of reply!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''N.B.:'' You cannot call() a method belonging to an application which has&lt;br /&gt;
registered with an unique numeric id appended to its textual name (see&lt;br /&gt;
dcopclient.h for more info). In this case, DCOP would not know which&lt;br /&gt;
application it should connect with to call the method. This is not an issue&lt;br /&gt;
with send(), as you can broadcast to all applications that have registered&lt;br /&gt;
with appname-&amp;amp;lt;numeric_id&amp;amp;gt; by using a wildcard (e.g. 'konsole-*'), which&lt;br /&gt;
will send your signal to all applications called 'konsole'.&lt;br /&gt;
&lt;br /&gt;
Since KDE 3.1 there is an even easier way to make a DCOP call:&lt;br /&gt;
{{class|DCOPRef|kdelibs|3.5}}. Then you only need to create a DCOPRef to the object&lt;br /&gt;
and as long as the function does not use unusual argument types,&lt;br /&gt;
calling the function is as easy as this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
DCOPRef barObject (&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;);&lt;br /&gt;
DCOPReply reply = barObject. call (&amp;quot;doIt&amp;quot;, 5);&lt;br /&gt;
if (!reply. isValid())&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    print(&amp;quot;the result is: %s&amp;quot;, ((QString)reply). latin1());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Receiving Data via DCOP ====&lt;br /&gt;
&lt;br /&gt;
Currently the only real way to receive data from DCOP is to multiply&lt;br /&gt;
inherit from the normal class that you are inheriting (usually some&lt;br /&gt;
sort of QWidget subclass or QObject) as well as the DCOPObject class.&lt;br /&gt;
DCOPObject provides one very important method: DCOPObject::process().&lt;br /&gt;
This is a pure virtual method that you must implement in order to&lt;br /&gt;
process DCOP messages that you receive.  It takes a function&lt;br /&gt;
signature, QByteArray of parameters, and a reference to a QByteArray&lt;br /&gt;
for the reply data that you must fill in.&lt;br /&gt;
&lt;br /&gt;
Think of DCOPObject::process() as a sort of dispatch agent.  In the&lt;br /&gt;
future, there will probably be a precompiler for your sources to write&lt;br /&gt;
this method for you.  However, until that point you need to examine&lt;br /&gt;
the incoming function signature and take action accordingly.  Here is&lt;br /&gt;
an example implementation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject::process(const QCString &amp;amp;amp;fun, const QByteArray &amp;amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;amp;replyType, QByteArray &amp;amp;amp;replyData)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg(data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;amp;gt;&amp;amp;gt; i;&lt;br /&gt;
        QString result = self-&amp;amp;gt;doIt (i);&lt;br /&gt;
        QDataStream reply(replyData, IO_WriteOnly);&lt;br /&gt;
        reply &amp;amp;lt;&amp;amp;lt; result;&lt;br /&gt;
        replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug(&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Processing Received Calls with Transactions ====&lt;br /&gt;
&lt;br /&gt;
If your applications is able to process incoming function calls&lt;br /&gt;
right away the above code is all you need. When your application&lt;br /&gt;
needs to do more complex tasks you might want to do the processing&lt;br /&gt;
out of 'process' function call and send the result back later when&lt;br /&gt;
it becomes available.&lt;br /&gt;
&lt;br /&gt;
For this you can ask your DCOPClient for a transactionId. You can&lt;br /&gt;
then return from the 'process' function and when the result is&lt;br /&gt;
available finish the transaction. In the mean time your application&lt;br /&gt;
can receive incoming DCOP function calls from other clients.&lt;br /&gt;
&lt;br /&gt;
Such code could like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject::process(const QCString &amp;amp;amp;fun, const QByteArray &amp;amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;amp;, QByteArray &amp;amp;amp;)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg(data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;amp;gt;&amp;amp;gt; i;&lt;br /&gt;
        QString result = self-&amp;amp;gt;doIt(i);&lt;br /&gt;
&lt;br /&gt;
        DCOPClientTransaction *myTransaction;&lt;br /&gt;
        myTransaction = kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;beginTransaction();&lt;br /&gt;
&lt;br /&gt;
        // start processing...&lt;br /&gt;
        // Calls slotProcessingDone when finished.&lt;br /&gt;
        startProcessing( myTransaction, i);&lt;br /&gt;
&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug(&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
slotProcessingDone(DCOPClientTransaction *myTransaction, const QString &amp;amp;amp;result)&lt;br /&gt;
{&lt;br /&gt;
    QCString replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
    QByteArray replyData;&lt;br /&gt;
    QDataStream reply(replyData, IO_WriteOnly);&lt;br /&gt;
    reply &amp;amp;lt;&amp;amp;lt; result;&lt;br /&gt;
    kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;endTransaction(myTransaction, replyType, replyData);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DCOP Signals ====&lt;br /&gt;
&lt;br /&gt;
Sometimes a component wants to send notifications via DCOP to other&lt;br /&gt;
components but does not know which components will be interested in these&lt;br /&gt;
notifications. One could use a broadcast in such a case but this is a very&lt;br /&gt;
crude method. For a more sophisticated method DCOP signals have been invented.&lt;br /&gt;
&lt;br /&gt;
DCOP signals are very similair to Qt signals, there are some differences &lt;br /&gt;
though. A DCOP signal can be connected to a DCOP function. Whenever the DCOP&lt;br /&gt;
signal gets emitted, the DCOP functions to which the signal is connected are&lt;br /&gt;
being called. DCOP signals are, just like Qt signals, one way. They do not&lt;br /&gt;
provide a return value. &lt;br /&gt;
&lt;br /&gt;
A DCOP signal originates from a DCOP Object/DCOP Client combination (sender). &lt;br /&gt;
It can be connected to a function of another DCOP Object/DCOP Client &lt;br /&gt;
combination (receiver).&lt;br /&gt;
&lt;br /&gt;
There are two major differences between connections of Qt signals and&lt;br /&gt;
connections of DCOP signals. In DCOP, unlike Qt, a signal connections can&lt;br /&gt;
have an anonymous sender and, unlike Qt, a DCOP signal connection can be&lt;br /&gt;
non-volatile.&lt;br /&gt;
&lt;br /&gt;
With DCOP one can connect a signal without specifying the sending DCOP Object &lt;br /&gt;
or DCOP Client. In that case signals from any DCOP Object and/or DCOP Client&lt;br /&gt;
will be delivered. This allows the specification of certain events without&lt;br /&gt;
tying oneself to a certain object that implementes the events.&lt;br /&gt;
&lt;br /&gt;
Another DCOP feature are so called non-volatile connections. With Qt signal&lt;br /&gt;
connections, the connection gets deleted when either sender or receiver of&lt;br /&gt;
the signal gets deleted. A volatile DCOP signal connection will behave the&lt;br /&gt;
same. However, a non-volatile DCOP signal connection will not get deleted &lt;br /&gt;
when the sending object gets deleted. Once a new object gets created with &lt;br /&gt;
the same name as the original sending object, the connection will be restored.&lt;br /&gt;
There is no difference between the two when the receiving object gets deleted,&lt;br /&gt;
in that case the signal connection will always be deleted.&lt;br /&gt;
&lt;br /&gt;
A receiver can create a non-volatile connection while the sender doesn't (yet)&lt;br /&gt;
exist. An anonymous DCOP connection should always be non-volatile.&lt;br /&gt;
&lt;br /&gt;
The following example shows how KLauncher emits a signal whenever it notices&lt;br /&gt;
that an application that was started via KLauncher terminates.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray params;&lt;br /&gt;
QDataStream stream(params, IO_WriteOnly);&lt;br /&gt;
stream &amp;amp;lt;&amp;amp;lt; pid;&lt;br /&gt;
kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;emitDCOPSignal(&amp;quot;clientDied(pid_t)&amp;quot;, params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The task manager of the KDE panel connects to this signal. It uses an &lt;br /&gt;
anonymous connection (it doesn't require that the signal is being emitted&lt;br /&gt;
by KLauncher) that is non-volatile:&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
connectDCOPSignal(0, 0, &amp;quot;clientDied(pid_t)&amp;quot;, &amp;quot;clientDied(pid_t)&amp;quot;, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It connects the clientDied(pid_t) signal to its own clientDied(pid_t) DCOP&lt;br /&gt;
function. In this case the signal and the function to call have the same name.&lt;br /&gt;
This isn't needed as long as the arguments of both signal and receiving function&lt;br /&gt;
match. The receiving function may ignore one or more of the trailing arguments&lt;br /&gt;
of the signal. E.g. it is allowed to connect the clientDied(pid_t) signal to&lt;br /&gt;
a clientDied(void) DCOP function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the dcopidl compiler ===&lt;br /&gt;
&lt;br /&gt;
dcopidl makes setting up a DCOP server easy. Instead of having to implement&lt;br /&gt;
the process() method and unmarshalling (retrieving from QByteArray) parameters&lt;br /&gt;
manually, you can let dcopidl create the necessary code on your behalf.&lt;br /&gt;
&lt;br /&gt;
This also allows you to describe the interface for your class in a&lt;br /&gt;
single, separate header file.&lt;br /&gt;
&lt;br /&gt;
Writing an IDL file is very similar to writing a normal C++ header. An&lt;br /&gt;
exception is the keyword 'ASYNC'. It indicates that a call to this&lt;br /&gt;
function shall be processed asynchronously. For the C++ compiler, it&lt;br /&gt;
expands to 'void'.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#ifndef MY_INTERFACE_H&lt;br /&gt;
#define MY_INTERFACE_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;amp;lt;dcopobject.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
class MyInterface : virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
&lt;br /&gt;
        virtual ASYNC myAsynchronousMethod(QString someParameter) = 0;&lt;br /&gt;
        virtual QRect mySynchronousMethod() = 0;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, you're essentially declaring an abstract base class, which&lt;br /&gt;
virtually inherits from DCOPObject.&lt;br /&gt;
&lt;br /&gt;
If you're using the standard KDE build scripts, then you can simply add this file (which you would call {{path|MyInterface.h}}) to your sources directory. Then you edit your {{path|Makefile.am}}, adding 'MyInterface.skel' to your SOURCES list and {{path|MyInterface.h}} to include_HEADERS.&lt;br /&gt;
&lt;br /&gt;
The build scripts will use dcopidl to parse {{path|MyInterface.h}}, converting it to an XML description in {{path|MyInterface.kidl}}. Next, a file called {{path|MyInterface_skel.cpp}} will automatically be created, compiled and linked with your binary.&lt;br /&gt;
&lt;br /&gt;
The next thing you have to do is to choose which of your classes will implement the interface described in {{path|MyInterface.h}}. Alter the inheritance of this class such that it virtually inherits from {{path|MyInterface}}. Then add declarations to your class interface similar to those on {{path|MyInterface.h}}, but virtual, not pure virtual.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public MyInterface&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: (Qt issue) Remember that if you are inheriting from {{qt3|QObject}}, you must place it first in the list of inherited classes.&lt;br /&gt;
&lt;br /&gt;
In the implementation of your class' ctor, you must explicitly initialize&lt;br /&gt;
those classes from which you are inheriting from. This is, of course, good&lt;br /&gt;
practise, but it is essential here as you need to tell DCOPObject the name of&lt;br /&gt;
the interface which your are implementing.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
MyClass::MyClass()&lt;br /&gt;
  : QObject(),&lt;br /&gt;
    DCOPObject(&amp;quot;MyInterface&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
    // whatever...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can simply implement the methods you have declared in your interface,&lt;br /&gt;
exactly the same as you would normally.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
void MyClass::myAsynchronousMethod(QString someParameter)&lt;br /&gt;
{&lt;br /&gt;
    qDebug(&amp;quot;myAsyncMethod called with param `&amp;quot; + someParameter + &amp;quot;'&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is not necessary (though very clean) to define an interface as an&lt;br /&gt;
abstract class of its own, like we did in the example above. We could&lt;br /&gt;
just as well have defined a k_dcop section directly within MyClass:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to skeletons, dcopidl2cpp also generate stubs. Those make&lt;br /&gt;
it easy to call a DCOP interface without doing the marshalling&lt;br /&gt;
manually. To use a stub, add {{path|MyInterface.stub}} to the SOURCES list of&lt;br /&gt;
your {{path|Makefile.am}}. The stub class will then be called MyInterface_stub.&lt;br /&gt;
&lt;br /&gt;
=== Inter-user communication ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it might be interesting to use DCOP between processes&lt;br /&gt;
belonging to different users, e.g. a frontend process running&lt;br /&gt;
with the user's id, and a backend process running as root.&lt;br /&gt;
&lt;br /&gt;
To do this, two steps have to be taken:&lt;br /&gt;
* both processes need to talk to the same DCOP server&lt;br /&gt;
* proper authentication must be ensured&lt;br /&gt;
&lt;br /&gt;
For the first step, you simply pass the server address (as&lt;br /&gt;
found in .DCOPserver) to the second process. For the authentication,&lt;br /&gt;
you can use the ICEAUTHORITY environment variable to tell the&lt;br /&gt;
second process where to find the authentication information.&lt;br /&gt;
(Note that this implies that the second process is able to&lt;br /&gt;
read the authentication file, so it will probably only work&lt;br /&gt;
if the second process runs as root. If it should run as another&lt;br /&gt;
user, a similar approach to what kdesu does with xauth must&lt;br /&gt;
be taken. In fact, it would be a very good idea to add DCOP&lt;br /&gt;
support to kdesu!)&lt;br /&gt;
&lt;br /&gt;
For example&lt;br /&gt;
 ICEAUTHORITY=~user/.ICEauthority kdesu root -c kcmroot -dcopserver `cat ~user/.DCOPserver`&lt;br /&gt;
&lt;br /&gt;
will, after kdesu got the root password, execute kcmroot as root, talking&lt;br /&gt;
to the user's dcop server.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' DCOP communication is not encrypted, so please do not&lt;br /&gt;
pass important information around this way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Performance Tests ==&lt;br /&gt;
&lt;br /&gt;
A few back-of-the-napkin tests folks:&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#include &amp;amp;lt;kapp.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    KApplication *app;&lt;br /&gt;
&lt;br /&gt;
    app = new KApplication(argc, argv, &amp;quot;testit&amp;quot;);&lt;br /&gt;
    return app-&amp;amp;gt;exec();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compiled with:&lt;br /&gt;
 g++ -O2 -o testit testit.cpp -I$QTDIR/include -L$QTDIR/lib -lkdecore&lt;br /&gt;
&lt;br /&gt;
on Linux yields the following memory use statistics:&lt;br /&gt;
 VmSize:     8076 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4532 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
If I create the KApplication's DCOPClient, and call attach() and&lt;br /&gt;
registerAs(), it changes to this:&lt;br /&gt;
 VmSize:     8080 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4624 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
Basically it appears that using DCOP causes 100k more memory to be&lt;br /&gt;
resident, but no more data or stack.  So this will be shared between all&lt;br /&gt;
processes, right?  100k to enable DCOP in all apps doesn't seem bad at&lt;br /&gt;
all. :)&lt;br /&gt;
&lt;br /&gt;
OK now for some timings.  Just creating a KApplication and then exiting&lt;br /&gt;
(i.e. removing the call to KApplication::exec) takes this much time:&lt;br /&gt;
&lt;br /&gt;
 0.28user 0.02system 0:00.32elapsed 92%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1084major+62minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second on my PII-233.  Now, if we create our DCOP&lt;br /&gt;
object and attach to the server, it takes this long:&lt;br /&gt;
&lt;br /&gt;
 0.27user 0.03system 0:00.34elapsed 87%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1107major+65minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second.  Basically DCOPClient creation and attaching&lt;br /&gt;
gets lost in the statistical variation (&amp;quot;noise&amp;quot;).  I was getting times&lt;br /&gt;
between .32 and .48 over several runs for both of the example programs, so&lt;br /&gt;
obviously system load is more relevant than the extra two calls to&lt;br /&gt;
DCOPClient::attach and DCOPClient::registerAs, as well as the actual&lt;br /&gt;
DCOPClient constructor time.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Hopefully this document will get you well on your way into the world&lt;br /&gt;
of inter-process communication with KDE! Please direct all comments&lt;br /&gt;
and/or suggestions to [mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] and [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;].&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE3]]&lt;br /&gt;
[[Category:Architecture]]&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/DCOP</id>
		<title>Development/Architecture/DCOP</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/DCOP"/>
				<updated>2010-05-22T22:03:00Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: /* Establishing the Connection */ unmark &amp;amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;border: 1px solid #2090ff; padding: 1em 1em 1em 1em; background-color:#f8f8ff; align:center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DCOP: Desktop COmmunications Protocol'''&lt;br /&gt;
&lt;br /&gt;
[mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] October 14, 1999&lt;br /&gt;
&lt;br /&gt;
Revised and extended by [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;] Mar 29, 2000&lt;br /&gt;
&lt;br /&gt;
HTMLized by Hans Meine [mailto:rastajoe@gmx.net Hans Meine &amp;amp;lt;rastajoe@gmx.net&amp;amp;gt;] May 25, 2000&lt;br /&gt;
&lt;br /&gt;
Added a DCOPRef example: Tim Jansen May 12, 2003&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Demotivation and Background ==&lt;br /&gt;
&lt;br /&gt;
'''Note that new features may not be developed for DCOP. The successor for DCOP is D-Bus'''&lt;br /&gt;
&lt;br /&gt;
The motivation behind building a protocol like DCOP is simple.  For&lt;br /&gt;
the past year, we have been attempting to enable interprocess&lt;br /&gt;
communication between KDE applications. KDE already has an extremely&lt;br /&gt;
simple IPC mechanism called KWMcom, which is (was!) used for communicating&lt;br /&gt;
between the panel and the window manager for instance.  It is about as&lt;br /&gt;
simple as it gets, passing messages via X Atoms.  For this reason it&lt;br /&gt;
is limited in the size and complexity of the data that can be passed&lt;br /&gt;
(X atoms must be small to remain efficient) and it also makes it so&lt;br /&gt;
that X is required.  CORBA was thought to be a more effective IPC/RPC&lt;br /&gt;
solution.  However, after a year of attempting to make heavy use of&lt;br /&gt;
CORBA in KDE, we have realized that it is a bit slow and memory&lt;br /&gt;
intensive for simple use.  It also has no authentication available.&lt;br /&gt;
&lt;br /&gt;
What we really needed was an extremely simple protocol with basic&lt;br /&gt;
authorization, along the lines of MIT-MAGIC-COOKIE, as used by X.  It&lt;br /&gt;
would not be able to do NEARLY what CORBA was able to do, but for the&lt;br /&gt;
simple tasks required it would be sufficient. Some examples of such&lt;br /&gt;
tasks might be an application sending a message to the panel saying,&lt;br /&gt;
&amp;quot;I have started, stop displaying the 'application starting' wait&lt;br /&gt;
state,&amp;quot; or having a new application that starts query to see if any&lt;br /&gt;
other applications of the same name are running.  If they are, simply&lt;br /&gt;
call a function on the remote application to create a new window,&lt;br /&gt;
rather than starting a new process.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
DCOP is a simple IPC/RPC mechanism built to operate over sockets.&lt;br /&gt;
Either unix domain sockets or tcp/ip sockets are supported. DCOP is&lt;br /&gt;
built on top of the Inter Client Exchange (ICE) protocol, which comes&lt;br /&gt;
standard as a part of X11R6 and later. It also depends on Qt, but&lt;br /&gt;
beyond that it does not require any other libraries. Because of this,&lt;br /&gt;
it is extremely lightweight, enabling it to be linked into all KDE&lt;br /&gt;
applications with low overhead.&lt;br /&gt;
&lt;br /&gt;
=== Model ===&lt;br /&gt;
&lt;br /&gt;
The model is simple.  Each application using DCOP is a client.  They&lt;br /&gt;
communicate to each other through a DCOP server, which functions like&lt;br /&gt;
a traffic director, dispatching messages/calls to the proper&lt;br /&gt;
destinations.  All clients are peers of each other.&lt;br /&gt;
&lt;br /&gt;
Two types of actions are possible with DCOP: &amp;quot;send and forget&amp;quot;&lt;br /&gt;
messages, which do not block, and &amp;quot;calls,&amp;quot; which block waiting for&lt;br /&gt;
some data to be returned.&lt;br /&gt;
&lt;br /&gt;
Any data that will be sent is serialized (marshalled, for you CORBA&lt;br /&gt;
fellows) using the built-in {{qt3|QDataStream}} operators available in all of&lt;br /&gt;
the Qt classes.  This is fast and easy.  In fact it's so little work&lt;br /&gt;
that you can easily write the marshalling code by hand. In addition,&lt;br /&gt;
there's a simple IDL-like compiler available (dcopidl and dcopidl2cpp)&lt;br /&gt;
that generates stubs and skeletons for you. Using the dcopidl compiler&lt;br /&gt;
has the additional benefit of type safety.&lt;br /&gt;
&lt;br /&gt;
This HOWTO describes the manual method first and covers the dcopidl&lt;br /&gt;
compiler later.&lt;br /&gt;
&lt;br /&gt;
=== Managing DCOP Connections Manually ===&lt;br /&gt;
&lt;br /&gt;
==== Establishing the Connection ====&lt;br /&gt;
&lt;br /&gt;
{{class|KApplication|kdelibs|3.5}} has gained a method called &amp;quot;KApplication::dcopClient()&amp;quot;&lt;br /&gt;
which returns a pointer to a DCOPClient instance.  The first time this&lt;br /&gt;
method is called, the client class will be created.  {{class|DCOPClient|kdelibs|3.5}}s have&lt;br /&gt;
unique identifiers attached to them which are based on what&lt;br /&gt;
KApplication::name() returns.  In fact, if there is only a single&lt;br /&gt;
instance of the program running, the appId will be equal to&lt;br /&gt;
KApplication::name().&lt;br /&gt;
&lt;br /&gt;
To actually enable DCOP communication to begin, you must use&lt;br /&gt;
DCOPClient::attach().  This will attempt to attach to the DCOP server.&lt;br /&gt;
If no server is found or there is any other type of error, attach()&lt;br /&gt;
will return false. KApplication will catch a dcop signal and display an&lt;br /&gt;
appropriate error message box in that case.&lt;br /&gt;
&lt;br /&gt;
After connecting with the server via DCOPClient::attach(), you need to&lt;br /&gt;
register this appId with the server so it knows about you.  Otherwise,&lt;br /&gt;
you are communicating anonymously.  Use the&lt;br /&gt;
DCOPClient::registerAs(const QCString &amp;amp;amp;name) to do so.  In the simple&lt;br /&gt;
case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * returns the appId that is actually registered, which _may_ be&lt;br /&gt;
 * different from what you passed&lt;br /&gt;
 */&lt;br /&gt;
appId = client -&amp;gt; registerAs (kApp -&amp;gt; name());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you never retrieve the DCOPClient pointer from KApplication, the&lt;br /&gt;
object will not be created and thus there will be no memory overhead.&lt;br /&gt;
&lt;br /&gt;
You may also detach from the server by calling DCOPClient::detach().&lt;br /&gt;
If you wish to attach again you will need to re-register as well.  If&lt;br /&gt;
you only wish to change the ID under which you are registered, simply&lt;br /&gt;
call DCOPClient::registerAs() with the new name.&lt;br /&gt;
&lt;br /&gt;
KUniqueApplication automatically registers itself to DCOP. If you&lt;br /&gt;
are using KUniqueApplication you should not attach or register&lt;br /&gt;
yourself, this is already done. The appId is by definition&lt;br /&gt;
equal to kapp-&amp;amp;gt;name(). You can retrieve the registered DCOP client&lt;br /&gt;
by calling kapp-&amp;amp;gt;dcopClient().&lt;br /&gt;
&lt;br /&gt;
==== Sending Data to a Remote Application ====&lt;br /&gt;
&lt;br /&gt;
To actually communicate, you have one of two choices.  You may either&lt;br /&gt;
call the &amp;quot;send&amp;quot; or the &amp;quot;call&amp;quot; method.  Both methods require three&lt;br /&gt;
identification parameters: an application identifier, a remote object,&lt;br /&gt;
a remote function. Sending is asynchronous (i.e. it returns immediately)&lt;br /&gt;
and may or may not result in your own application being sent a message at&lt;br /&gt;
some point in the future. Then &amp;quot;send&amp;quot; requires one and &amp;quot;call&amp;quot; requires&lt;br /&gt;
two data parameters.&lt;br /&gt;
&lt;br /&gt;
The remote object must be specified as an object hierarchy.  That is,&lt;br /&gt;
if the toplevel object is called &amp;quot;fooObject&amp;quot; and has the child&lt;br /&gt;
&amp;quot;barObject&amp;quot;, you would reference this object as &amp;quot;fooObject/barObject&amp;quot;.&lt;br /&gt;
Functions must be described by a full function signature.  If the&lt;br /&gt;
remote function is called &amp;quot;doIt&amp;quot;, and it takes an int, it would be&lt;br /&gt;
described as &amp;quot;doIt(int)&amp;quot;.  Please note that the return type is not&lt;br /&gt;
specified here, as it is not part of the function signature (or at&lt;br /&gt;
least the C++ understanding of a function signature).  You will get&lt;br /&gt;
the return type of a function back as an extra parameter to&lt;br /&gt;
DCOPClient::call().  See the section on call() for more details.&lt;br /&gt;
&lt;br /&gt;
In order to actually get the data to the remote client, it must be&lt;br /&gt;
&amp;quot;serialized&amp;quot; via a {{qt3|QDataStream}} operating on a {{qt3|QByteArray}}. This is how&lt;br /&gt;
the data parameter is &amp;quot;built&amp;quot;. A few examples will make clear how this&lt;br /&gt;
works.&lt;br /&gt;
&lt;br /&gt;
Say you want to call &amp;quot;doIt&amp;quot; as described above, and not block (or wait&lt;br /&gt;
for a response).  You will not receive the return value of the remotely&lt;br /&gt;
called function, but you will not hang while the RPC is processed either.&lt;br /&gt;
The return value of send() indicates whether DCOP communication succeeded&lt;br /&gt;
or not.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data;&lt;br /&gt;
QDataStream arg(data, IO_WriteOnly);&lt;br /&gt;
arg &amp;amp;lt;&amp;amp;lt; 5;&lt;br /&gt;
if (!client-&amp;amp;gt;send(&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data))&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OK, now let's say we wanted to get the data back from the remotely&lt;br /&gt;
called function.  You have to execute a call() instead of a send().&lt;br /&gt;
The returned value will then be available in the data parameter &amp;quot;reply&amp;quot;.&lt;br /&gt;
The actual return value of call() is still whether or not DCOP&lt;br /&gt;
communication was successful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data, replyData;&lt;br /&gt;
QCString replyType;&lt;br /&gt;
QDataStream arg(data, IO_WriteOnly);&lt;br /&gt;
arg &amp;amp;lt;&amp;amp;lt; 5;&lt;br /&gt;
if (!client-&amp;amp;gt;call(&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data, replyType, replyData))&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    QDataStream reply(replyData, IO_ReadOnly);&lt;br /&gt;
    if (replyType == &amp;quot;QString&amp;quot;) {&lt;br /&gt;
        QString result;&lt;br /&gt;
        reply &amp;amp;gt;&amp;amp;gt; result;&lt;br /&gt;
        print(&amp;quot;the result is: %s&amp;quot;,result.latin1());&lt;br /&gt;
    } else&lt;br /&gt;
        qDebug(&amp;quot;doIt returned an unexpected type of reply!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''N.B.:'' You cannot call() a method belonging to an application which has&lt;br /&gt;
registered with an unique numeric id appended to its textual name (see&lt;br /&gt;
dcopclient.h for more info). In this case, DCOP would not know which&lt;br /&gt;
application it should connect with to call the method. This is not an issue&lt;br /&gt;
with send(), as you can broadcast to all applications that have registered&lt;br /&gt;
with appname-&amp;amp;lt;numeric_id&amp;amp;gt; by using a wildcard (e.g. 'konsole-*'), which&lt;br /&gt;
will send your signal to all applications called 'konsole'.&lt;br /&gt;
&lt;br /&gt;
Since KDE 3.1 there is an even easier way to make a DCOP call:&lt;br /&gt;
{{class|DCOPRef|kdelibs|3.5}}. Then you only need to create a DCOPRef to the object&lt;br /&gt;
and as long as the function does not use unusual argument types,&lt;br /&gt;
calling the function is as easy as this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
DCOPRef barObject(&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;);&lt;br /&gt;
DCOPReply reply = barObject.call(&amp;quot;doIt&amp;quot;, 5);&lt;br /&gt;
if (!reply.isValid())&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    print(&amp;quot;the result is: %s&amp;quot;, ((QString)reply).latin1());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Receiving Data via DCOP ====&lt;br /&gt;
&lt;br /&gt;
Currently the only real way to receive data from DCOP is to multiply&lt;br /&gt;
inherit from the normal class that you are inheriting (usually some&lt;br /&gt;
sort of QWidget subclass or QObject) as well as the DCOPObject class.&lt;br /&gt;
DCOPObject provides one very important method: DCOPObject::process().&lt;br /&gt;
This is a pure virtual method that you must implement in order to&lt;br /&gt;
process DCOP messages that you receive.  It takes a function&lt;br /&gt;
signature, QByteArray of parameters, and a reference to a QByteArray&lt;br /&gt;
for the reply data that you must fill in.&lt;br /&gt;
&lt;br /&gt;
Think of DCOPObject::process() as a sort of dispatch agent.  In the&lt;br /&gt;
future, there will probably be a precompiler for your sources to write&lt;br /&gt;
this method for you.  However, until that point you need to examine&lt;br /&gt;
the incoming function signature and take action accordingly.  Here is&lt;br /&gt;
an example implementation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject::process(const QCString &amp;amp;amp;fun, const QByteArray &amp;amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;amp;replyType, QByteArray &amp;amp;amp;replyData)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg(data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;amp;gt;&amp;amp;gt; i;&lt;br /&gt;
        QString result = self-&amp;amp;gt;doIt (i);&lt;br /&gt;
        QDataStream reply(replyData, IO_WriteOnly);&lt;br /&gt;
        reply &amp;amp;lt;&amp;amp;lt; result;&lt;br /&gt;
        replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug(&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Processing Received Calls with Transactions ====&lt;br /&gt;
&lt;br /&gt;
If your applications is able to process incoming function calls&lt;br /&gt;
right away the above code is all you need. When your application&lt;br /&gt;
needs to do more complex tasks you might want to do the processing&lt;br /&gt;
out of 'process' function call and send the result back later when&lt;br /&gt;
it becomes available.&lt;br /&gt;
&lt;br /&gt;
For this you can ask your DCOPClient for a transactionId. You can&lt;br /&gt;
then return from the 'process' function and when the result is&lt;br /&gt;
available finish the transaction. In the mean time your application&lt;br /&gt;
can receive incoming DCOP function calls from other clients.&lt;br /&gt;
&lt;br /&gt;
Such code could like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject::process(const QCString &amp;amp;amp;fun, const QByteArray &amp;amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;amp;, QByteArray &amp;amp;amp;)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg(data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;amp;gt;&amp;amp;gt; i;&lt;br /&gt;
        QString result = self-&amp;amp;gt;doIt(i);&lt;br /&gt;
&lt;br /&gt;
        DCOPClientTransaction *myTransaction;&lt;br /&gt;
        myTransaction = kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;beginTransaction();&lt;br /&gt;
&lt;br /&gt;
        // start processing...&lt;br /&gt;
        // Calls slotProcessingDone when finished.&lt;br /&gt;
        startProcessing( myTransaction, i);&lt;br /&gt;
&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug(&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
slotProcessingDone(DCOPClientTransaction *myTransaction, const QString &amp;amp;amp;result)&lt;br /&gt;
{&lt;br /&gt;
    QCString replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
    QByteArray replyData;&lt;br /&gt;
    QDataStream reply(replyData, IO_WriteOnly);&lt;br /&gt;
    reply &amp;amp;lt;&amp;amp;lt; result;&lt;br /&gt;
    kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;endTransaction(myTransaction, replyType, replyData);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DCOP Signals ====&lt;br /&gt;
&lt;br /&gt;
Sometimes a component wants to send notifications via DCOP to other&lt;br /&gt;
components but does not know which components will be interested in these&lt;br /&gt;
notifications. One could use a broadcast in such a case but this is a very&lt;br /&gt;
crude method. For a more sophisticated method DCOP signals have been invented.&lt;br /&gt;
&lt;br /&gt;
DCOP signals are very similair to Qt signals, there are some differences &lt;br /&gt;
though. A DCOP signal can be connected to a DCOP function. Whenever the DCOP&lt;br /&gt;
signal gets emitted, the DCOP functions to which the signal is connected are&lt;br /&gt;
being called. DCOP signals are, just like Qt signals, one way. They do not&lt;br /&gt;
provide a return value. &lt;br /&gt;
&lt;br /&gt;
A DCOP signal originates from a DCOP Object/DCOP Client combination (sender). &lt;br /&gt;
It can be connected to a function of another DCOP Object/DCOP Client &lt;br /&gt;
combination (receiver).&lt;br /&gt;
&lt;br /&gt;
There are two major differences between connections of Qt signals and&lt;br /&gt;
connections of DCOP signals. In DCOP, unlike Qt, a signal connections can&lt;br /&gt;
have an anonymous sender and, unlike Qt, a DCOP signal connection can be&lt;br /&gt;
non-volatile.&lt;br /&gt;
&lt;br /&gt;
With DCOP one can connect a signal without specifying the sending DCOP Object &lt;br /&gt;
or DCOP Client. In that case signals from any DCOP Object and/or DCOP Client&lt;br /&gt;
will be delivered. This allows the specification of certain events without&lt;br /&gt;
tying oneself to a certain object that implementes the events.&lt;br /&gt;
&lt;br /&gt;
Another DCOP feature are so called non-volatile connections. With Qt signal&lt;br /&gt;
connections, the connection gets deleted when either sender or receiver of&lt;br /&gt;
the signal gets deleted. A volatile DCOP signal connection will behave the&lt;br /&gt;
same. However, a non-volatile DCOP signal connection will not get deleted &lt;br /&gt;
when the sending object gets deleted. Once a new object gets created with &lt;br /&gt;
the same name as the original sending object, the connection will be restored.&lt;br /&gt;
There is no difference between the two when the receiving object gets deleted,&lt;br /&gt;
in that case the signal connection will always be deleted.&lt;br /&gt;
&lt;br /&gt;
A receiver can create a non-volatile connection while the sender doesn't (yet)&lt;br /&gt;
exist. An anonymous DCOP connection should always be non-volatile.&lt;br /&gt;
&lt;br /&gt;
The following example shows how KLauncher emits a signal whenever it notices&lt;br /&gt;
that an application that was started via KLauncher terminates.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray params;&lt;br /&gt;
QDataStream stream(params, IO_WriteOnly);&lt;br /&gt;
stream &amp;amp;lt;&amp;amp;lt; pid;&lt;br /&gt;
kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;emitDCOPSignal(&amp;quot;clientDied(pid_t)&amp;quot;, params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The task manager of the KDE panel connects to this signal. It uses an &lt;br /&gt;
anonymous connection (it doesn't require that the signal is being emitted&lt;br /&gt;
by KLauncher) that is non-volatile:&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
connectDCOPSignal(0, 0, &amp;quot;clientDied(pid_t)&amp;quot;, &amp;quot;clientDied(pid_t)&amp;quot;, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It connects the clientDied(pid_t) signal to its own clientDied(pid_t) DCOP&lt;br /&gt;
function. In this case the signal and the function to call have the same name.&lt;br /&gt;
This isn't needed as long as the arguments of both signal and receiving function&lt;br /&gt;
match. The receiving function may ignore one or more of the trailing arguments&lt;br /&gt;
of the signal. E.g. it is allowed to connect the clientDied(pid_t) signal to&lt;br /&gt;
a clientDied(void) DCOP function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the dcopidl compiler ===&lt;br /&gt;
&lt;br /&gt;
dcopidl makes setting up a DCOP server easy. Instead of having to implement&lt;br /&gt;
the process() method and unmarshalling (retrieving from QByteArray) parameters&lt;br /&gt;
manually, you can let dcopidl create the necessary code on your behalf.&lt;br /&gt;
&lt;br /&gt;
This also allows you to describe the interface for your class in a&lt;br /&gt;
single, separate header file.&lt;br /&gt;
&lt;br /&gt;
Writing an IDL file is very similar to writing a normal C++ header. An&lt;br /&gt;
exception is the keyword 'ASYNC'. It indicates that a call to this&lt;br /&gt;
function shall be processed asynchronously. For the C++ compiler, it&lt;br /&gt;
expands to 'void'.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#ifndef MY_INTERFACE_H&lt;br /&gt;
#define MY_INTERFACE_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;amp;lt;dcopobject.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
class MyInterface : virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
&lt;br /&gt;
        virtual ASYNC myAsynchronousMethod(QString someParameter) = 0;&lt;br /&gt;
        virtual QRect mySynchronousMethod() = 0;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, you're essentially declaring an abstract base class, which&lt;br /&gt;
virtually inherits from DCOPObject.&lt;br /&gt;
&lt;br /&gt;
If you're using the standard KDE build scripts, then you can simply add this file (which you would call {{path|MyInterface.h}}) to your sources directory. Then you edit your {{path|Makefile.am}}, adding 'MyInterface.skel' to your SOURCES list and {{path|MyInterface.h}} to include_HEADERS.&lt;br /&gt;
&lt;br /&gt;
The build scripts will use dcopidl to parse {{path|MyInterface.h}}, converting it to an XML description in {{path|MyInterface.kidl}}. Next, a file called {{path|MyInterface_skel.cpp}} will automatically be created, compiled and linked with your binary.&lt;br /&gt;
&lt;br /&gt;
The next thing you have to do is to choose which of your classes will implement the interface described in {{path|MyInterface.h}}. Alter the inheritance of this class such that it virtually inherits from {{path|MyInterface}}. Then add declarations to your class interface similar to those on {{path|MyInterface.h}}, but virtual, not pure virtual.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public MyInterface&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: (Qt issue) Remember that if you are inheriting from {{qt3|QObject}}, you must place it first in the list of inherited classes.&lt;br /&gt;
&lt;br /&gt;
In the implementation of your class' ctor, you must explicitly initialize&lt;br /&gt;
those classes from which you are inheriting from. This is, of course, good&lt;br /&gt;
practise, but it is essential here as you need to tell DCOPObject the name of&lt;br /&gt;
the interface which your are implementing.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
MyClass::MyClass()&lt;br /&gt;
  : QObject(),&lt;br /&gt;
    DCOPObject(&amp;quot;MyInterface&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
    // whatever...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can simply implement the methods you have declared in your interface,&lt;br /&gt;
exactly the same as you would normally.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
void MyClass::myAsynchronousMethod(QString someParameter)&lt;br /&gt;
{&lt;br /&gt;
    qDebug(&amp;quot;myAsyncMethod called with param `&amp;quot; + someParameter + &amp;quot;'&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is not necessary (though very clean) to define an interface as an&lt;br /&gt;
abstract class of its own, like we did in the example above. We could&lt;br /&gt;
just as well have defined a k_dcop section directly within MyClass:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to skeletons, dcopidl2cpp also generate stubs. Those make&lt;br /&gt;
it easy to call a DCOP interface without doing the marshalling&lt;br /&gt;
manually. To use a stub, add {{path|MyInterface.stub}} to the SOURCES list of&lt;br /&gt;
your {{path|Makefile.am}}. The stub class will then be called MyInterface_stub.&lt;br /&gt;
&lt;br /&gt;
=== Inter-user communication ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it might be interesting to use DCOP between processes&lt;br /&gt;
belonging to different users, e.g. a frontend process running&lt;br /&gt;
with the user's id, and a backend process running as root.&lt;br /&gt;
&lt;br /&gt;
To do this, two steps have to be taken:&lt;br /&gt;
* both processes need to talk to the same DCOP server&lt;br /&gt;
* proper authentication must be ensured&lt;br /&gt;
&lt;br /&gt;
For the first step, you simply pass the server address (as&lt;br /&gt;
found in .DCOPserver) to the second process. For the authentication,&lt;br /&gt;
you can use the ICEAUTHORITY environment variable to tell the&lt;br /&gt;
second process where to find the authentication information.&lt;br /&gt;
(Note that this implies that the second process is able to&lt;br /&gt;
read the authentication file, so it will probably only work&lt;br /&gt;
if the second process runs as root. If it should run as another&lt;br /&gt;
user, a similar approach to what kdesu does with xauth must&lt;br /&gt;
be taken. In fact, it would be a very good idea to add DCOP&lt;br /&gt;
support to kdesu!)&lt;br /&gt;
&lt;br /&gt;
For example&lt;br /&gt;
 ICEAUTHORITY=~user/.ICEauthority kdesu root -c kcmroot -dcopserver `cat ~user/.DCOPserver`&lt;br /&gt;
&lt;br /&gt;
will, after kdesu got the root password, execute kcmroot as root, talking&lt;br /&gt;
to the user's dcop server.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' DCOP communication is not encrypted, so please do not&lt;br /&gt;
pass important information around this way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Performance Tests ==&lt;br /&gt;
&lt;br /&gt;
A few back-of-the-napkin tests folks:&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#include &amp;amp;lt;kapp.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    KApplication *app;&lt;br /&gt;
&lt;br /&gt;
    app = new KApplication(argc, argv, &amp;quot;testit&amp;quot;);&lt;br /&gt;
    return app-&amp;amp;gt;exec();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compiled with:&lt;br /&gt;
 g++ -O2 -o testit testit.cpp -I$QTDIR/include -L$QTDIR/lib -lkdecore&lt;br /&gt;
&lt;br /&gt;
on Linux yields the following memory use statistics:&lt;br /&gt;
 VmSize:     8076 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4532 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
If I create the KApplication's DCOPClient, and call attach() and&lt;br /&gt;
registerAs(), it changes to this:&lt;br /&gt;
 VmSize:     8080 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4624 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
Basically it appears that using DCOP causes 100k more memory to be&lt;br /&gt;
resident, but no more data or stack.  So this will be shared between all&lt;br /&gt;
processes, right?  100k to enable DCOP in all apps doesn't seem bad at&lt;br /&gt;
all. :)&lt;br /&gt;
&lt;br /&gt;
OK now for some timings.  Just creating a KApplication and then exiting&lt;br /&gt;
(i.e. removing the call to KApplication::exec) takes this much time:&lt;br /&gt;
&lt;br /&gt;
 0.28user 0.02system 0:00.32elapsed 92%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1084major+62minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second on my PII-233.  Now, if we create our DCOP&lt;br /&gt;
object and attach to the server, it takes this long:&lt;br /&gt;
&lt;br /&gt;
 0.27user 0.03system 0:00.34elapsed 87%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1107major+65minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second.  Basically DCOPClient creation and attaching&lt;br /&gt;
gets lost in the statistical variation (&amp;quot;noise&amp;quot;).  I was getting times&lt;br /&gt;
between .32 and .48 over several runs for both of the example programs, so&lt;br /&gt;
obviously system load is more relevant than the extra two calls to&lt;br /&gt;
DCOPClient::attach and DCOPClient::registerAs, as well as the actual&lt;br /&gt;
DCOPClient constructor time.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Hopefully this document will get you well on your way into the world&lt;br /&gt;
of inter-process communication with KDE! Please direct all comments&lt;br /&gt;
and/or suggestions to [mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] and [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;].&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE3]]&lt;br /&gt;
[[Category:Architecture]]&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/DCOP</id>
		<title>Development/Architecture/DCOP</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/DCOP"/>
				<updated>2010-05-22T22:01:08Z</updated>
		
		<summary type="html">&lt;p&gt;Yecril71pl: s/cppqt3/cpp-qt/&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;border: 1px solid #2090ff; padding: 1em 1em 1em 1em; background-color:#f8f8ff; align:center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''DCOP: Desktop COmmunications Protocol'''&lt;br /&gt;
&lt;br /&gt;
[mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] October 14, 1999&lt;br /&gt;
&lt;br /&gt;
Revised and extended by [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;] Mar 29, 2000&lt;br /&gt;
&lt;br /&gt;
HTMLized by Hans Meine [mailto:rastajoe@gmx.net Hans Meine &amp;amp;lt;rastajoe@gmx.net&amp;amp;gt;] May 25, 2000&lt;br /&gt;
&lt;br /&gt;
Added a DCOPRef example: Tim Jansen May 12, 2003&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Demotivation and Background ==&lt;br /&gt;
&lt;br /&gt;
'''Note that new features may not be developed for DCOP. The successor for DCOP is D-Bus'''&lt;br /&gt;
&lt;br /&gt;
The motivation behind building a protocol like DCOP is simple.  For&lt;br /&gt;
the past year, we have been attempting to enable interprocess&lt;br /&gt;
communication between KDE applications. KDE already has an extremely&lt;br /&gt;
simple IPC mechanism called KWMcom, which is (was!) used for communicating&lt;br /&gt;
between the panel and the window manager for instance.  It is about as&lt;br /&gt;
simple as it gets, passing messages via X Atoms.  For this reason it&lt;br /&gt;
is limited in the size and complexity of the data that can be passed&lt;br /&gt;
(X atoms must be small to remain efficient) and it also makes it so&lt;br /&gt;
that X is required.  CORBA was thought to be a more effective IPC/RPC&lt;br /&gt;
solution.  However, after a year of attempting to make heavy use of&lt;br /&gt;
CORBA in KDE, we have realized that it is a bit slow and memory&lt;br /&gt;
intensive for simple use.  It also has no authentication available.&lt;br /&gt;
&lt;br /&gt;
What we really needed was an extremely simple protocol with basic&lt;br /&gt;
authorization, along the lines of MIT-MAGIC-COOKIE, as used by X.  It&lt;br /&gt;
would not be able to do NEARLY what CORBA was able to do, but for the&lt;br /&gt;
simple tasks required it would be sufficient. Some examples of such&lt;br /&gt;
tasks might be an application sending a message to the panel saying,&lt;br /&gt;
&amp;quot;I have started, stop displaying the 'application starting' wait&lt;br /&gt;
state,&amp;quot; or having a new application that starts query to see if any&lt;br /&gt;
other applications of the same name are running.  If they are, simply&lt;br /&gt;
call a function on the remote application to create a new window,&lt;br /&gt;
rather than starting a new process.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
DCOP is a simple IPC/RPC mechanism built to operate over sockets.&lt;br /&gt;
Either unix domain sockets or tcp/ip sockets are supported. DCOP is&lt;br /&gt;
built on top of the Inter Client Exchange (ICE) protocol, which comes&lt;br /&gt;
standard as a part of X11R6 and later. It also depends on Qt, but&lt;br /&gt;
beyond that it does not require any other libraries. Because of this,&lt;br /&gt;
it is extremely lightweight, enabling it to be linked into all KDE&lt;br /&gt;
applications with low overhead.&lt;br /&gt;
&lt;br /&gt;
=== Model ===&lt;br /&gt;
&lt;br /&gt;
The model is simple.  Each application using DCOP is a client.  They&lt;br /&gt;
communicate to each other through a DCOP server, which functions like&lt;br /&gt;
a traffic director, dispatching messages/calls to the proper&lt;br /&gt;
destinations.  All clients are peers of each other.&lt;br /&gt;
&lt;br /&gt;
Two types of actions are possible with DCOP: &amp;quot;send and forget&amp;quot;&lt;br /&gt;
messages, which do not block, and &amp;quot;calls,&amp;quot; which block waiting for&lt;br /&gt;
some data to be returned.&lt;br /&gt;
&lt;br /&gt;
Any data that will be sent is serialized (marshalled, for you CORBA&lt;br /&gt;
fellows) using the built-in {{qt3|QDataStream}} operators available in all of&lt;br /&gt;
the Qt classes.  This is fast and easy.  In fact it's so little work&lt;br /&gt;
that you can easily write the marshalling code by hand. In addition,&lt;br /&gt;
there's a simple IDL-like compiler available (dcopidl and dcopidl2cpp)&lt;br /&gt;
that generates stubs and skeletons for you. Using the dcopidl compiler&lt;br /&gt;
has the additional benefit of type safety.&lt;br /&gt;
&lt;br /&gt;
This HOWTO describes the manual method first and covers the dcopidl&lt;br /&gt;
compiler later.&lt;br /&gt;
&lt;br /&gt;
=== Managing DCOP Connections Manually ===&lt;br /&gt;
&lt;br /&gt;
==== Establishing the Connection ====&lt;br /&gt;
&lt;br /&gt;
{{class|KApplication|kdelibs|3.5}} has gained a method called &amp;quot;KApplication::dcopClient()&amp;quot;&lt;br /&gt;
which returns a pointer to a DCOPClient instance.  The first time this&lt;br /&gt;
method is called, the client class will be created.  {{class|DCOPClient|kdelibs|3.5}}s have&lt;br /&gt;
unique identifiers attached to them which are based on what&lt;br /&gt;
KApplication::name() returns.  In fact, if there is only a single&lt;br /&gt;
instance of the program running, the appId will be equal to&lt;br /&gt;
KApplication::name().&lt;br /&gt;
&lt;br /&gt;
To actually enable DCOP communication to begin, you must use&lt;br /&gt;
DCOPClient::attach().  This will attempt to attach to the DCOP server.&lt;br /&gt;
If no server is found or there is any other type of error, attach()&lt;br /&gt;
will return false. KApplication will catch a dcop signal and display an&lt;br /&gt;
appropriate error message box in that case.&lt;br /&gt;
&lt;br /&gt;
After connecting with the server via DCOPClient::attach(), you need to&lt;br /&gt;
register this appId with the server so it knows about you.  Otherwise,&lt;br /&gt;
you are communicating anonymously.  Use the&lt;br /&gt;
DCOPClient::registerAs(const QCString &amp;amp;amp;name) to do so.  In the simple&lt;br /&gt;
case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * returns the appId that is actually registered, which _may_ be&lt;br /&gt;
 * different from what you passed&lt;br /&gt;
 */&lt;br /&gt;
appId = client-&amp;amp;gt;registerAs(kApp-&amp;amp;gt;name());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you never retrieve the DCOPClient pointer from KApplication, the&lt;br /&gt;
object will not be created and thus there will be no memory overhead.&lt;br /&gt;
&lt;br /&gt;
You may also detach from the server by calling DCOPClient::detach().&lt;br /&gt;
If you wish to attach again you will need to re-register as well.  If&lt;br /&gt;
you only wish to change the ID under which you are registered, simply&lt;br /&gt;
call DCOPClient::registerAs() with the new name.&lt;br /&gt;
&lt;br /&gt;
KUniqueApplication automatically registers itself to DCOP. If you&lt;br /&gt;
are using KUniqueApplication you should not attach or register&lt;br /&gt;
yourself, this is already done. The appId is by definition&lt;br /&gt;
equal to kapp-&amp;amp;gt;name(). You can retrieve the registered DCOP client&lt;br /&gt;
by calling kapp-&amp;amp;gt;dcopClient().&lt;br /&gt;
&lt;br /&gt;
==== Sending Data to a Remote Application ====&lt;br /&gt;
&lt;br /&gt;
To actually communicate, you have one of two choices.  You may either&lt;br /&gt;
call the &amp;quot;send&amp;quot; or the &amp;quot;call&amp;quot; method.  Both methods require three&lt;br /&gt;
identification parameters: an application identifier, a remote object,&lt;br /&gt;
a remote function. Sending is asynchronous (i.e. it returns immediately)&lt;br /&gt;
and may or may not result in your own application being sent a message at&lt;br /&gt;
some point in the future. Then &amp;quot;send&amp;quot; requires one and &amp;quot;call&amp;quot; requires&lt;br /&gt;
two data parameters.&lt;br /&gt;
&lt;br /&gt;
The remote object must be specified as an object hierarchy.  That is,&lt;br /&gt;
if the toplevel object is called &amp;quot;fooObject&amp;quot; and has the child&lt;br /&gt;
&amp;quot;barObject&amp;quot;, you would reference this object as &amp;quot;fooObject/barObject&amp;quot;.&lt;br /&gt;
Functions must be described by a full function signature.  If the&lt;br /&gt;
remote function is called &amp;quot;doIt&amp;quot;, and it takes an int, it would be&lt;br /&gt;
described as &amp;quot;doIt(int)&amp;quot;.  Please note that the return type is not&lt;br /&gt;
specified here, as it is not part of the function signature (or at&lt;br /&gt;
least the C++ understanding of a function signature).  You will get&lt;br /&gt;
the return type of a function back as an extra parameter to&lt;br /&gt;
DCOPClient::call().  See the section on call() for more details.&lt;br /&gt;
&lt;br /&gt;
In order to actually get the data to the remote client, it must be&lt;br /&gt;
&amp;quot;serialized&amp;quot; via a {{qt3|QDataStream}} operating on a {{qt3|QByteArray}}. This is how&lt;br /&gt;
the data parameter is &amp;quot;built&amp;quot;. A few examples will make clear how this&lt;br /&gt;
works.&lt;br /&gt;
&lt;br /&gt;
Say you want to call &amp;quot;doIt&amp;quot; as described above, and not block (or wait&lt;br /&gt;
for a response).  You will not receive the return value of the remotely&lt;br /&gt;
called function, but you will not hang while the RPC is processed either.&lt;br /&gt;
The return value of send() indicates whether DCOP communication succeeded&lt;br /&gt;
or not.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data;&lt;br /&gt;
QDataStream arg(data, IO_WriteOnly);&lt;br /&gt;
arg &amp;amp;lt;&amp;amp;lt; 5;&lt;br /&gt;
if (!client-&amp;amp;gt;send(&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data))&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OK, now let's say we wanted to get the data back from the remotely&lt;br /&gt;
called function.  You have to execute a call() instead of a send().&lt;br /&gt;
The returned value will then be available in the data parameter &amp;quot;reply&amp;quot;.&lt;br /&gt;
The actual return value of call() is still whether or not DCOP&lt;br /&gt;
communication was successful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray data, replyData;&lt;br /&gt;
QCString replyType;&lt;br /&gt;
QDataStream arg(data, IO_WriteOnly);&lt;br /&gt;
arg &amp;amp;lt;&amp;amp;lt; 5;&lt;br /&gt;
if (!client-&amp;amp;gt;call(&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;, &amp;quot;doIt(int)&amp;quot;,&lt;br /&gt;
                     data, replyType, replyData))&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    QDataStream reply(replyData, IO_ReadOnly);&lt;br /&gt;
    if (replyType == &amp;quot;QString&amp;quot;) {&lt;br /&gt;
        QString result;&lt;br /&gt;
        reply &amp;amp;gt;&amp;amp;gt; result;&lt;br /&gt;
        print(&amp;quot;the result is: %s&amp;quot;,result.latin1());&lt;br /&gt;
    } else&lt;br /&gt;
        qDebug(&amp;quot;doIt returned an unexpected type of reply!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''N.B.:'' You cannot call() a method belonging to an application which has&lt;br /&gt;
registered with an unique numeric id appended to its textual name (see&lt;br /&gt;
dcopclient.h for more info). In this case, DCOP would not know which&lt;br /&gt;
application it should connect with to call the method. This is not an issue&lt;br /&gt;
with send(), as you can broadcast to all applications that have registered&lt;br /&gt;
with appname-&amp;amp;lt;numeric_id&amp;amp;gt; by using a wildcard (e.g. 'konsole-*'), which&lt;br /&gt;
will send your signal to all applications called 'konsole'.&lt;br /&gt;
&lt;br /&gt;
Since KDE 3.1 there is an even easier way to make a DCOP call:&lt;br /&gt;
{{class|DCOPRef|kdelibs|3.5}}. Then you only need to create a DCOPRef to the object&lt;br /&gt;
and as long as the function does not use unusual argument types,&lt;br /&gt;
calling the function is as easy as this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
DCOPRef barObject(&amp;quot;someAppId&amp;quot;, &amp;quot;fooObject/barObject&amp;quot;);&lt;br /&gt;
DCOPReply reply = barObject.call(&amp;quot;doIt&amp;quot;, 5);&lt;br /&gt;
if (!reply.isValid())&lt;br /&gt;
    qDebug(&amp;quot;there was some error using DCOP.&amp;quot;);&lt;br /&gt;
else {&lt;br /&gt;
    print(&amp;quot;the result is: %s&amp;quot;, ((QString)reply).latin1());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Receiving Data via DCOP ====&lt;br /&gt;
&lt;br /&gt;
Currently the only real way to receive data from DCOP is to multiply&lt;br /&gt;
inherit from the normal class that you are inheriting (usually some&lt;br /&gt;
sort of QWidget subclass or QObject) as well as the DCOPObject class.&lt;br /&gt;
DCOPObject provides one very important method: DCOPObject::process().&lt;br /&gt;
This is a pure virtual method that you must implement in order to&lt;br /&gt;
process DCOP messages that you receive.  It takes a function&lt;br /&gt;
signature, QByteArray of parameters, and a reference to a QByteArray&lt;br /&gt;
for the reply data that you must fill in.&lt;br /&gt;
&lt;br /&gt;
Think of DCOPObject::process() as a sort of dispatch agent.  In the&lt;br /&gt;
future, there will probably be a precompiler for your sources to write&lt;br /&gt;
this method for you.  However, until that point you need to examine&lt;br /&gt;
the incoming function signature and take action accordingly.  Here is&lt;br /&gt;
an example implementation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject::process(const QCString &amp;amp;amp;fun, const QByteArray &amp;amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;amp;replyType, QByteArray &amp;amp;amp;replyData)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg(data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;amp;gt;&amp;amp;gt; i;&lt;br /&gt;
        QString result = self-&amp;amp;gt;doIt (i);&lt;br /&gt;
        QDataStream reply(replyData, IO_WriteOnly);&lt;br /&gt;
        reply &amp;amp;lt;&amp;amp;lt; result;&lt;br /&gt;
        replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug(&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Processing Received Calls with Transactions ====&lt;br /&gt;
&lt;br /&gt;
If your applications is able to process incoming function calls&lt;br /&gt;
right away the above code is all you need. When your application&lt;br /&gt;
needs to do more complex tasks you might want to do the processing&lt;br /&gt;
out of 'process' function call and send the result back later when&lt;br /&gt;
it becomes available.&lt;br /&gt;
&lt;br /&gt;
For this you can ask your DCOPClient for a transactionId. You can&lt;br /&gt;
then return from the 'process' function and when the result is&lt;br /&gt;
available finish the transaction. In the mean time your application&lt;br /&gt;
can receive incoming DCOP function calls from other clients.&lt;br /&gt;
&lt;br /&gt;
Such code could like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
bool BarObject::process(const QCString &amp;amp;amp;fun, const QByteArray &amp;amp;amp;data,&lt;br /&gt;
                        QCString &amp;amp;amp;, QByteArray &amp;amp;amp;)&lt;br /&gt;
{&lt;br /&gt;
    if (fun == &amp;quot;doIt(int)&amp;quot;) {&lt;br /&gt;
        QDataStream arg(data, IO_ReadOnly);&lt;br /&gt;
        int i; // parameter&lt;br /&gt;
        arg &amp;amp;gt;&amp;amp;gt; i;&lt;br /&gt;
        QString result = self-&amp;amp;gt;doIt(i);&lt;br /&gt;
&lt;br /&gt;
        DCOPClientTransaction *myTransaction;&lt;br /&gt;
        myTransaction = kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;beginTransaction();&lt;br /&gt;
&lt;br /&gt;
        // start processing...&lt;br /&gt;
        // Calls slotProcessingDone when finished.&lt;br /&gt;
        startProcessing( myTransaction, i);&lt;br /&gt;
&lt;br /&gt;
        return true;&lt;br /&gt;
    } else {&lt;br /&gt;
        qDebug(&amp;quot;unknown function call to BarObject::process()&amp;quot;);&lt;br /&gt;
        return false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
slotProcessingDone(DCOPClientTransaction *myTransaction, const QString &amp;amp;amp;result)&lt;br /&gt;
{&lt;br /&gt;
    QCString replyType = &amp;quot;QString&amp;quot;;&lt;br /&gt;
    QByteArray replyData;&lt;br /&gt;
    QDataStream reply(replyData, IO_WriteOnly);&lt;br /&gt;
    reply &amp;amp;lt;&amp;amp;lt; result;&lt;br /&gt;
    kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;endTransaction(myTransaction, replyType, replyData);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DCOP Signals ====&lt;br /&gt;
&lt;br /&gt;
Sometimes a component wants to send notifications via DCOP to other&lt;br /&gt;
components but does not know which components will be interested in these&lt;br /&gt;
notifications. One could use a broadcast in such a case but this is a very&lt;br /&gt;
crude method. For a more sophisticated method DCOP signals have been invented.&lt;br /&gt;
&lt;br /&gt;
DCOP signals are very similair to Qt signals, there are some differences &lt;br /&gt;
though. A DCOP signal can be connected to a DCOP function. Whenever the DCOP&lt;br /&gt;
signal gets emitted, the DCOP functions to which the signal is connected are&lt;br /&gt;
being called. DCOP signals are, just like Qt signals, one way. They do not&lt;br /&gt;
provide a return value. &lt;br /&gt;
&lt;br /&gt;
A DCOP signal originates from a DCOP Object/DCOP Client combination (sender). &lt;br /&gt;
It can be connected to a function of another DCOP Object/DCOP Client &lt;br /&gt;
combination (receiver).&lt;br /&gt;
&lt;br /&gt;
There are two major differences between connections of Qt signals and&lt;br /&gt;
connections of DCOP signals. In DCOP, unlike Qt, a signal connections can&lt;br /&gt;
have an anonymous sender and, unlike Qt, a DCOP signal connection can be&lt;br /&gt;
non-volatile.&lt;br /&gt;
&lt;br /&gt;
With DCOP one can connect a signal without specifying the sending DCOP Object &lt;br /&gt;
or DCOP Client. In that case signals from any DCOP Object and/or DCOP Client&lt;br /&gt;
will be delivered. This allows the specification of certain events without&lt;br /&gt;
tying oneself to a certain object that implementes the events.&lt;br /&gt;
&lt;br /&gt;
Another DCOP feature are so called non-volatile connections. With Qt signal&lt;br /&gt;
connections, the connection gets deleted when either sender or receiver of&lt;br /&gt;
the signal gets deleted. A volatile DCOP signal connection will behave the&lt;br /&gt;
same. However, a non-volatile DCOP signal connection will not get deleted &lt;br /&gt;
when the sending object gets deleted. Once a new object gets created with &lt;br /&gt;
the same name as the original sending object, the connection will be restored.&lt;br /&gt;
There is no difference between the two when the receiving object gets deleted,&lt;br /&gt;
in that case the signal connection will always be deleted.&lt;br /&gt;
&lt;br /&gt;
A receiver can create a non-volatile connection while the sender doesn't (yet)&lt;br /&gt;
exist. An anonymous DCOP connection should always be non-volatile.&lt;br /&gt;
&lt;br /&gt;
The following example shows how KLauncher emits a signal whenever it notices&lt;br /&gt;
that an application that was started via KLauncher terminates.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
QByteArray params;&lt;br /&gt;
QDataStream stream(params, IO_WriteOnly);&lt;br /&gt;
stream &amp;amp;lt;&amp;amp;lt; pid;&lt;br /&gt;
kapp-&amp;amp;gt;dcopClient()-&amp;amp;gt;emitDCOPSignal(&amp;quot;clientDied(pid_t)&amp;quot;, params);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The task manager of the KDE panel connects to this signal. It uses an &lt;br /&gt;
anonymous connection (it doesn't require that the signal is being emitted&lt;br /&gt;
by KLauncher) that is non-volatile:&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
connectDCOPSignal(0, 0, &amp;quot;clientDied(pid_t)&amp;quot;, &amp;quot;clientDied(pid_t)&amp;quot;, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It connects the clientDied(pid_t) signal to its own clientDied(pid_t) DCOP&lt;br /&gt;
function. In this case the signal and the function to call have the same name.&lt;br /&gt;
This isn't needed as long as the arguments of both signal and receiving function&lt;br /&gt;
match. The receiving function may ignore one or more of the trailing arguments&lt;br /&gt;
of the signal. E.g. it is allowed to connect the clientDied(pid_t) signal to&lt;br /&gt;
a clientDied(void) DCOP function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the dcopidl compiler ===&lt;br /&gt;
&lt;br /&gt;
dcopidl makes setting up a DCOP server easy. Instead of having to implement&lt;br /&gt;
the process() method and unmarshalling (retrieving from QByteArray) parameters&lt;br /&gt;
manually, you can let dcopidl create the necessary code on your behalf.&lt;br /&gt;
&lt;br /&gt;
This also allows you to describe the interface for your class in a&lt;br /&gt;
single, separate header file.&lt;br /&gt;
&lt;br /&gt;
Writing an IDL file is very similar to writing a normal C++ header. An&lt;br /&gt;
exception is the keyword 'ASYNC'. It indicates that a call to this&lt;br /&gt;
function shall be processed asynchronously. For the C++ compiler, it&lt;br /&gt;
expands to 'void'.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#ifndef MY_INTERFACE_H&lt;br /&gt;
#define MY_INTERFACE_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;amp;lt;dcopobject.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
class MyInterface : virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
&lt;br /&gt;
        virtual ASYNC myAsynchronousMethod(QString someParameter) = 0;&lt;br /&gt;
        virtual QRect mySynchronousMethod() = 0;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, you're essentially declaring an abstract base class, which&lt;br /&gt;
virtually inherits from DCOPObject.&lt;br /&gt;
&lt;br /&gt;
If you're using the standard KDE build scripts, then you can simply add this file (which you would call {{path|MyInterface.h}}) to your sources directory. Then you edit your {{path|Makefile.am}}, adding 'MyInterface.skel' to your SOURCES list and {{path|MyInterface.h}} to include_HEADERS.&lt;br /&gt;
&lt;br /&gt;
The build scripts will use dcopidl to parse {{path|MyInterface.h}}, converting it to an XML description in {{path|MyInterface.kidl}}. Next, a file called {{path|MyInterface_skel.cpp}} will automatically be created, compiled and linked with your binary.&lt;br /&gt;
&lt;br /&gt;
The next thing you have to do is to choose which of your classes will implement the interface described in {{path|MyInterface.h}}. Alter the inheritance of this class such that it virtually inherits from {{path|MyInterface}}. Then add declarations to your class interface similar to those on {{path|MyInterface.h}}, but virtual, not pure virtual.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public MyInterface&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: (Qt issue) Remember that if you are inheriting from {{qt3|QObject}}, you must place it first in the list of inherited classes.&lt;br /&gt;
&lt;br /&gt;
In the implementation of your class' ctor, you must explicitly initialize&lt;br /&gt;
those classes from which you are inheriting from. This is, of course, good&lt;br /&gt;
practise, but it is essential here as you need to tell DCOPObject the name of&lt;br /&gt;
the interface which your are implementing.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
MyClass::MyClass()&lt;br /&gt;
  : QObject(),&lt;br /&gt;
    DCOPObject(&amp;quot;MyInterface&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
    // whatever...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can simply implement the methods you have declared in your interface,&lt;br /&gt;
exactly the same as you would normally.&lt;br /&gt;
&lt;br /&gt;
; Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
void MyClass::myAsynchronousMethod(QString someParameter)&lt;br /&gt;
{&lt;br /&gt;
    qDebug(&amp;quot;myAsyncMethod called with param `&amp;quot; + someParameter + &amp;quot;'&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is not necessary (though very clean) to define an interface as an&lt;br /&gt;
abstract class of its own, like we did in the example above. We could&lt;br /&gt;
just as well have defined a k_dcop section directly within MyClass:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
class MyClass: public QObject, virtual public DCOPObject&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
    K_DCOP&lt;br /&gt;
&lt;br /&gt;
    public:&lt;br /&gt;
        MyClass();&lt;br /&gt;
        ~MyClass();&lt;br /&gt;
&lt;br /&gt;
    k_dcop:&lt;br /&gt;
        ASYNC myAsynchronousMethod(QString someParameter);&lt;br /&gt;
        QRect mySynchronousMethod();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to skeletons, dcopidl2cpp also generate stubs. Those make&lt;br /&gt;
it easy to call a DCOP interface without doing the marshalling&lt;br /&gt;
manually. To use a stub, add {{path|MyInterface.stub}} to the SOURCES list of&lt;br /&gt;
your {{path|Makefile.am}}. The stub class will then be called MyInterface_stub.&lt;br /&gt;
&lt;br /&gt;
=== Inter-user communication ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it might be interesting to use DCOP between processes&lt;br /&gt;
belonging to different users, e.g. a frontend process running&lt;br /&gt;
with the user's id, and a backend process running as root.&lt;br /&gt;
&lt;br /&gt;
To do this, two steps have to be taken:&lt;br /&gt;
* both processes need to talk to the same DCOP server&lt;br /&gt;
* proper authentication must be ensured&lt;br /&gt;
&lt;br /&gt;
For the first step, you simply pass the server address (as&lt;br /&gt;
found in .DCOPserver) to the second process. For the authentication,&lt;br /&gt;
you can use the ICEAUTHORITY environment variable to tell the&lt;br /&gt;
second process where to find the authentication information.&lt;br /&gt;
(Note that this implies that the second process is able to&lt;br /&gt;
read the authentication file, so it will probably only work&lt;br /&gt;
if the second process runs as root. If it should run as another&lt;br /&gt;
user, a similar approach to what kdesu does with xauth must&lt;br /&gt;
be taken. In fact, it would be a very good idea to add DCOP&lt;br /&gt;
support to kdesu!)&lt;br /&gt;
&lt;br /&gt;
For example&lt;br /&gt;
 ICEAUTHORITY=~user/.ICEauthority kdesu root -c kcmroot -dcopserver `cat ~user/.DCOPserver`&lt;br /&gt;
&lt;br /&gt;
will, after kdesu got the root password, execute kcmroot as root, talking&lt;br /&gt;
to the user's dcop server.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' DCOP communication is not encrypted, so please do not&lt;br /&gt;
pass important information around this way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Performance Tests ==&lt;br /&gt;
&lt;br /&gt;
A few back-of-the-napkin tests folks:&lt;br /&gt;
&lt;br /&gt;
Code:&lt;br /&gt;
&amp;lt;code cpp-qt&amp;gt;&lt;br /&gt;
#include &amp;amp;lt;kapp.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    KApplication *app;&lt;br /&gt;
&lt;br /&gt;
    app = new KApplication(argc, argv, &amp;quot;testit&amp;quot;);&lt;br /&gt;
    return app-&amp;amp;gt;exec();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compiled with:&lt;br /&gt;
 g++ -O2 -o testit testit.cpp -I$QTDIR/include -L$QTDIR/lib -lkdecore&lt;br /&gt;
&lt;br /&gt;
on Linux yields the following memory use statistics:&lt;br /&gt;
 VmSize:     8076 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4532 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
If I create the KApplication's DCOPClient, and call attach() and&lt;br /&gt;
registerAs(), it changes to this:&lt;br /&gt;
 VmSize:     8080 kB&lt;br /&gt;
 VmLck:         0 kB&lt;br /&gt;
 VmRSS:      4624 kB&lt;br /&gt;
 VmData:      208 kB&lt;br /&gt;
 VmStk:        20 kB&lt;br /&gt;
 VmExe:         4 kB&lt;br /&gt;
 VmLib:      6588 kB&lt;br /&gt;
&lt;br /&gt;
Basically it appears that using DCOP causes 100k more memory to be&lt;br /&gt;
resident, but no more data or stack.  So this will be shared between all&lt;br /&gt;
processes, right?  100k to enable DCOP in all apps doesn't seem bad at&lt;br /&gt;
all. :)&lt;br /&gt;
&lt;br /&gt;
OK now for some timings.  Just creating a KApplication and then exiting&lt;br /&gt;
(i.e. removing the call to KApplication::exec) takes this much time:&lt;br /&gt;
&lt;br /&gt;
 0.28user 0.02system 0:00.32elapsed 92%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1084major+62minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second on my PII-233.  Now, if we create our DCOP&lt;br /&gt;
object and attach to the server, it takes this long:&lt;br /&gt;
&lt;br /&gt;
 0.27user 0.03system 0:00.34elapsed 87%CPU (0avgtext+0avgdata 0maxresident)k&lt;br /&gt;
 0inputs+0outputs (1107major+65minor)pagefaults 0swaps&lt;br /&gt;
&lt;br /&gt;
I.e. about 1/3 of a second.  Basically DCOPClient creation and attaching&lt;br /&gt;
gets lost in the statistical variation (&amp;quot;noise&amp;quot;).  I was getting times&lt;br /&gt;
between .32 and .48 over several runs for both of the example programs, so&lt;br /&gt;
obviously system load is more relevant than the extra two calls to&lt;br /&gt;
DCOPClient::attach and DCOPClient::registerAs, as well as the actual&lt;br /&gt;
DCOPClient constructor time.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Hopefully this document will get you well on your way into the world&lt;br /&gt;
of inter-process communication with KDE! Please direct all comments&lt;br /&gt;
and/or suggestions to [mailto:pbrown@kde.org Preston Brown &amp;amp;lt;pbrown@kde.org&amp;amp;gt;] and [mailto:ettrich@kde.org Matthias Ettrich &amp;amp;lt;ettrich@kde.org&amp;amp;gt;].&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE3]]&lt;br /&gt;
[[Category:Architecture]]&lt;/div&gt;</summary>
		<author><name>Yecril71pl</name></author>	</entry>

	</feed>