<chapter id="tinkering-under-the-hood">

<title>Tinkering Under the Hood of &tde;</title>

<sect1 id="hand-editing-config-files">

<title>Hand-Editing Configuration Files</title>

<sect2 id="hand-editing-intro">
<title>Introduction</title>
<para>In &tde;, the configuration files are easy to edit with a simple
editor like &kate; as the configuration files are text files.</para>

<para>An example of a text file:</para>

<programlisting>[General]
AutoSave=1
LastFile=/var/tmp/test.txt</programlisting>

<para>The user-specific configuration files are stored in <filename
class="directory">.kde/share/config</filename> (replace 
<filename>.kde</filename> with your $<envar>TDEHOME</envar> setting) and
the global ones are in the <filename
class="directory">share/config</filename> sub-directory of &tde;'s
installation path. (You can find this path by running the command
<command>tde-config --prefix</command>.) Their filenames typically
end in rc (without an initial period), for example <filename>kopeterc</filename>.</para>

<warning><para>
Editing configuration files by hand can risk the stability of your
&tde; installation. Applications usually do  not check what they read from the
configuration files. This means that they can be disturbed by what they
get as configuration and might even
crash.</para></warning>

</sect2>

<sect2 id="hand-editing-backups">
<title>Backups</title>

<para>So the first rule is to make a backup of your file before modifying
it. The backup is better stored outside any
<filename class="directory">.kde</filename> subdirectory 
(or the corresponding $<envar>TDEHOME</envar> directory). Backups are anyway
a good idea in case of a major failure of &tde; that would
destroy important configuration files (for example your &kmail;  settings,
which are in in the file <filename>kmailrc</filename>).
(Such a major failure should not happen but it still can happen.)</para>
</sect2>

<sect2 id="hand-editing">
<title>Editing</title>

<para>So why would you want to touch the configuration files at all? Well, first you need it
when you want to enforce the KIOSK mode. Perhaps a developer has asked you
to add an entry to help them to solve a problem with the application. Perhaps you want to recover from
a problem without having to remove all the <filename
class="directory">.kde</filename> directory. Perhaps you want to learn more
about the depths of &tde;.</para>

<para>Anyway, whatever your reason, you want to modify by hand a
configuration file.</para>

<para>When planning to edit such a file, make sure that the application
using it is not running. If it is one of the basic configuration files,
consider editing the file while &tde; is not running at all.</para>

<para>Ready? So make a backup of the file (Did I tell you this already?),
start you favorite editor (let us assume it is &kate;), load the file
(Be careful to load as UTF-8, &kate; displays it as
<quote>utf8</quote>).</para>

<para>Now you have a file like:</para>

<programlisting>[Group]
Key1=Value1
Key2=Value2
Key3=Value3</programlisting>

<para>You can now modify it (with care!) and then save it (Be sure that it
is as <acronym>UTF-8</acronym> again).</para>

<para>Now you can test the application and if the application does not run
correctly anymore, close the application and restore the backup of the
configuration file.</para>

<!--<itemizedlist>
<title>Related Information</title>


<listitem><para><ulink url="help:/khelpcenter/adminguide">The &tde;
Administrator Guide</ulink> has more
information about the &tde; directory structure, to help you find the
file you need to edit.</para>
</listitem>

</itemizedlist>-->

</sect2>

</sect1>

<sect1 id="scripting-the-desktop">
<title>Scripting the Desktop</title>

<para>&tde; provides a powerful interprocess communication system in
&DCOP;, the Desktop COmmunication Protocol. Using &DCOP;, you can
control a wide range of functions in &tde; from the command line or
from a script written in your favorite scripting language. You can
also get information out of &tde; applications: for example, several
&tde; media players provide methods to query the player for
information about the currently-playing track.</para>

<para>Broadly speaking, each &tde; application provides one or more
&DCOP; <firstterm>interfaces</firstterm>, which in turn provide
methods (or, if you prefer, functions) that another application can
call. So, the first step in using &DCOP; is to find the appropriate
method for the task. The easiest way to do this is using the
<application>kdcop</application> frontend to the available &DCOP;
methods.</para>

<para>Run <application>kdcop</application> from a &konsole; or the
mini-<acronym>CLI</acronym> (the window which pops up on <keycombo
action="simul">&Alt;<keycap>F2</keycap> </keycombo>). The
<application>kdcop</application> window shows the applications
currently running which provide &DCOP; interfaces, using a tree
view. 
<!-- TODO: Describe the search lineedit thingy -->
In general, finding the correct method requires a little bit of
searching through the tree view, but a useful hint is that the
interface marked <quote>(default)</quote> usually contains the most
frequently-used functions.</para>



<para>To test that the function does what we expect, double-click on
the <guilabel>setColor</guilabel> entry. To set the color
<varname>c</varname>, click on the color selector button, and choose a
color. Set whether the color should be color A with the
checkbox. Click <guilabel>OK</guilabel> and the background color is
set.</para>

<para>To access the &DCOP; method from your favorite scripting
language, you can either use &DCOP; bindings, if available in the
tdebindings module, or call the <command>dcop</command> command-line
application. For simple usage, calling the
<command>dcop</command> command-line application is sufficient. To
call a &DCOP; method on the command line, we need to specify the
application and interface owning the method, the method itself, and
the arguments, in a form suitable for the shell.</para>

<para>We specify the application, interface and method in that order,
followed by the arguments in the same order that they are shown in
<application>kdcop</application>.  <command>dcop</command>
has plenty of other options: take a look at the output of
<userinput><command>dcop</command>
<option>--help</option></userinput>.</para>

<para>That's enough theory: time for an example:</para>

<example>
<title>A Background Color Changing Script with &DCOP;</title>

<para>With the <command>dcop</command> command-line application and a
little bit of Perl, we're going to make a simple script which slowly
cycles the desktop background through the spectrum.</para>

<para>Firstly, we look for the appropriate method with
<application>kdcop</application>. For this example, we'll short
circuit the searching, and go straight to it: the method we want is
<menuchoice><guimenu>kdesktop</guimenu><guisubmenu>KBackgroundIface</guisubmenu><guimenuitem>setColor</guimenuitem>
</menuchoice>. The arguments and return type of the function are shown
in the style of the C++ language. For
<methodname>setColor</methodname>, the arguments are a color,
<varname>c</varname>, which specifies the new background color, and a
boolean (true or false) value, <varname>isColorA</varname>, which
specifies whether the color is the first or second (this is useful for
setting gradients and so on).</para>

<para>To use our <methodname>setColor</methodname> method on the
command line, we use the following:

<screen>
<prompt>%</prompt> <userinput><command>dcop</command> kdesktop KBackgroundIface setColor '#ffffff' false</userinput>
</screen>
</para>

<para>To specify the color, we used the
hexadecimal RGB value, as used in &HTML;. Note that it is enclosed in
single quotes to protect the <token>#</token> from the shell.</para>

<para>To find the hexadecimal RGB value of a color, open any
color chooser dialog in a &tde; application (for example, in
&kcontrolcenter;, <menuchoice><guimenu>Appearance &amp; Themes</guimenu><guimenuitem>Colors</guimenuitem>
</menuchoice>), select the color you want, and use the value given in
the <guilabel>HTML</guilabel> text box.</para>


<para>So, that's all we need from &DCOP;; now it's just a case of
writing a script around it. Here's a (very!) rough implementation:

<programlisting>
<![CDATA[
$min=49;  # Minimum value of R, G, or B colour
$max=174; # Maximum value of R, G, or B colour
$step=5;  # Amount to step colour by on each step
$sleeptime=15; # Interval in seconds between each step

@start = ($max, $min, $min);
@colour = @start;

while (1) {
	foreach (0..5) {
		my $which = $_ % 3; # Which colour (R, G or B) to change
		my $updown = $_ % 2; # Whether to increase or decrease the colour value
		do {
			if ($updown == 0) { $colour[$which]+=$step; }
			if ($updown == 1) { $colour[$which]-=$step; }
			my $dcopcall=sprintf "dcop kdesktop KBackgroundIface setColor '#%x%x%x' true\n", @colour;
			system($dcopcall);
			sleep $sleeptime;
			} while (($colour[$which] >= $min) and ($colour[$which] <= $max));
		}
}
]]>
</programlisting>
</para>

<para>Just run the script with no arguments, and it will cycle the
background colour through a slightly muted spectrum until it is
killed. <foreignphrase>Voil&agrave;</foreignphrase>!</para>

</example>

<para>Of course, Perl isn't the only language you can use to write
scripts with &DCOP;&mdash;if you prefer shell scripting, that's
available too:</para>

<example>
<title>Setting a background from the Internet</title>

<para>The following script gets the main image from the <quote>User
Friendly</quote> comic strip and sets it as the desktop wallpaper,
using commonly available tools and a little bit of &DCOP;:</para>

<programlisting>
<![CDATA[
#!/bin/sh
COMICURL=`wget -qO - http://www.userfriendly.org/static/index.html | \
          grep Latest | sed -e "s,.*SRC=\",," -e "s,\">.*,,"`
TMPFILE=`mktemp /tmp/$0.XXXXXX` || exit 1
wget -q -O $TMPFILE $COMICURL
dcop kdesktop KBackgroundIface setWallpaper $TMPFILE 1
]]>
</programlisting>

<para>The first line after the #!/bin/sh uses <command>wget</command> and some regular
expression magic to extract the image location from the main page's
&HTML; source. The second and third lines download the image, and
finally, <command>dcop</command> sets the downloaded image as
wallpaper.</para>

</example>


<!-- <itemizedlist>
<title>Related Information</title>
<listitem><para>to be written</para>
</listitem>
</itemizedlist> -->


</sect1>


<sect1 id="adding-extra-keys">
<title>Adding Extra Keybindings to &tde;</title>

<para>Many modern keyboards contain extra keys that are not by default
assigned to any action.</para>

<para><quote>Multimedia</quote> keys often generate a signal, and can simply
be chosen as a keybinding within an application just like choosing any other
key. Some keys however, are not detected and pressing them in a
<guilabel>Configure Shortcuts</guilabel> has no effect.</para>

<para>Some IBM laptops, for instance, have extra keys about the left and right
arrows, which look like <guiicon>page left</guiicon> and <guiicon>page
right</guiicon>.</para>

<procedure>
<step><para>Use <command>xev</command> to find the code of the keys.  In
this case, they are 233 and 234 <!-- TODO: Very briefly how to use xev here -->
</para></step>
<step><para>Choose key symbols. There are quite a range of these that are not
used by default, so many are free.  You can find the list in
<filename>/usr/X11R6/include/X11/keysymdef.h</filename> (or its equivalent
on your system).</para></step>
<step><para>Create a file in your home directory called
<filename>.Xmodmap</filename>, and add to it the following:</para>
<screen>keycode 233 = Next_Virtual_Screen
keycode 234 = Prev_Virtual_Screen</screen>
</step>
<step><para>Run the command <userinput><command>xmodmap</command>
<filename>~/.Xmodmap</filename></userinput></para></step>
</procedure>

<para>At this point, you should be able to run <command>xev</command> again
and see that the keys now generate the keysym that you assigned.  You can now
simply assign them to any action as normal.</para>

<itemizedlist>
<title>Related Information</title>
<listitem><para>The <command>xev</command> manpage.  You can see this by typing
<userinput>man:/xev</userinput> into a &konqueror; window or by typing
<userinput><command>man</command> xev</userinput> into a terminal.</para></listitem>
</itemizedlist>

</sect1>

<sect1 id="keys-for-scripts">
<title>Adding Keybindings for New Actions</title>

<para>Most actions in either the desktop or in applications are readily
available to assign a keybinding to.  If the action you want a
shortcut for is something you wrote yourself, or is otherwise not available,
you can still assign a shortcut.</para>

<para>To bring together the two previous sections, perhaps you want to
assign an otherwise unused key on your keyboard to a script or dcop
command. Our example here will be to assign the two keys we added
in <xref linkend="adding-extra-keys"/> to go to the previous or
next virtual desktop, two functions for which you will need DCOP (as discussed in
<xref linkend="scripting-the-desktop"/>).</para>

<para>This can be achieved easily using the following method:</para>

<procedure>
<step>
<para>Open &kcontrol;, and in the <guilabel>Regional &amp; Accessibility</guilabel>
section, select <guilabel>Input Action</guilabel></para>
</step>
<step>
<para>Choose <guibutton>New Action</guibutton></para>
</step>
<step>
<para>Name the new action, &eg; <userinput>Next Virtual
Screen</userinput></para>
</step>
<step>
<para>Select <guilabel>Keyboard shortcut -> Command/URL (simple)</guilabel>
for the <guilabel>Action type:</guilabel></para>
</step>
<step>
<para>In the <guilabel>Keyboard Shortcut</guilabel> tab, click the button
you wish to use to trigger the command.  For this example, you would press
the one with the <guiicon>Next Page</guiicon> picture on it.
<keysym>Next_Virtual_Screen</keysym> will appear in the key image.</para>
</step>
<step>
<para>In the <guilabel>Command/URL Settings</guilabel> tab, enter the
command to run in the field: <userinput><command>dcop twin default
nextDesktop</command></userinput></para>
</step>
</procedure>

<para>Repeat the above with the <keysym>Prev_Virtual_Screen</keysym> key and
<userinput><command>dcop twin default
previousDesktop</command></userinput>.</para>

<para>Now pressing the <keysym>Prev_Virtual_Screen</keysym> or
<keysym>Next_Virtual_Screen</keysym> will switch you to the previous or next
virtual desktop, respectively.</para>

<para>Obviously you can assign any free key to any action.</para>

<itemizedlist>
<title>Related Information</title> 
<listitem><para>See the <application>KHotKeys</application> documentation by
looking it up in &khelpcenter;, or typing
<userinput>help:/khotkeys</userinput> in a &konqueror;
window.</para></listitem> 
<listitem><para><xref linkend="adding-extra-keys"/></para></listitem>
<listitem><para><xref linkend="scripting-the-desktop"/></para></listitem>
</itemizedlist>

</sect1>

<sect1 id="tdedebugdialog">

<title>&tdedebugdialog;  - Controlling &tde;'s Debugging Output</title>

<sect2 id="tdedebugdialog-basic-usage">
<title>Basic Usage</title>

<para>&tdedebugdialog; is not in the &kmenu; by default. You will need to run
it from the shell or from the mini-CLI <!-- link to CLI, for sure --> with
the command <userinput><command>tdedebugdialog</command></userinput>.
&tdedebugdialog; pops up a window with a long list of debugging areas. Each
area has a checkbox that you can check or uncheck <!-- perhaps
select/deselect --> in order to enable or disable debugging output for
that part of &tde;.</para>

<para>The list of debugging areas is sorted numerically, not alphabetically,
so tdeio (127) comes before artskde (400). The numbers go up to 200000 or so,
but there are really only 400 areas. You don't have to scroll through the
entire list to find the area you need, though. There is a line edit <!--
text-entry ? --> box at the top of the dialog where you can enter a part of
the name of the area you want. The list of entries that is displayed is
filtered to include only those debug areas that contain the text you have
entered. &eg; entering <userinput>k</userinput> does not filter very much at
all, but entering <userinput>kont</userinput> <!-- that's "butt" in dutch,
haha --> will show you just the &kontact; debugging areas. As an even
quicker way of enabling or disabling debugging output, there are also
<guibutton>select all</guibutton> and <guibutton>deselect all</guibutton>
buttons which will cause &tde; to produce a mountain of debugging output, or
very little.</para>
</sect2>

<sect2 id="tdedebugdialog-fullmode">
<title>TDEDebugDialog in full mode</title>

<!-- this text partly taken from the tdedebugdialog handbook -->

<para>In full mode, which is what you get when you start tdedebugdialog as
<userinput><command>tdedebugdialog</command>
<option>--fullmode</option></userinput>, the same list of debugging areas
as in plain mode is available, but you can select only one at a time from a
drop-down <!-- combo? --> box. You may then  independently set the output
for various types of messages: Information, Warning, Error and Fatal Error.
For each of these types, you can choose where the messages are sent. The
choices are:</para>

<para>File, in which case you can enter a filename. This file is written into your
$<envar>HOME</envar> directory.</para>

<para>Message Box. Each debugging message is displayed in an information dialog,
which you must <guibutton>OK</guibutton> to continue with the
application.</para>

<para>Shell, the default entry. Messages are printed to stderr, and will appear
 either in the shell window where the application was started, or
in <filename>.xsession-errors</filename>.</para>

<para>Syslog. This sends each debugging message to the system's syslog facility,
which can perform its own processing of the message.</para>

<para>None. This suppresses the output of this type of message.</para>

<para>For messages generated by  fatal errors, it is generally a bad idea to choose
None or Syslog, since in both cases you most likely will not see the message
and the application that encounters the fatal error will vanish without
leaving a clue as to why it vanishes. Whether or not the application will
vanish on fatal errors can be controlled by the checkbox <guilabel>abort on
fatal errors</guilabel>, which is checked by default &mdash; but you might
expect an application to crash (in a messy fashion) if a fatal error is
encountered anyway.</para>

<!-- Add links to "further reading" here -->
<!-- <itemizedlist>
<title>Related Information</title>
<listitem><para>to be written</para>
</listitem>
</itemizedlist>-->



</sect2>
</sect1>
</chapter>
