From 27856879bf962f178d88e79144e37a47e731b122 Mon Sep 17 00:00:00 2001
From: tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>
Date: Fri, 3 Sep 2010 09:14:57 +0000
Subject: * Massive import of OpenSUSE patches, primarily for bugfixes * Added
 some infrastructure created by OpenSUSE to allow for future addition of the
 Kickoff menu as an option * Minor Slackware compilation fixes

git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1171255 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
---
 kcheckpass/checkpass_pam.c                         |  11 +-
 kcontrol/background/bgdialog.cpp                   |  14 +-
 kcontrol/input/xcursor/themepage.cpp               |  11 +-
 kcontrol/kicker/menutab_impl.h                     |   3 +
 kcontrol/spellchecking/spellchecking.cpp           |   2 +-
 kdeeject/kdeeject                                  |  42 +-
 kdesktop/KDesktopIface.h                           |  29 +
 kdesktop/Makefile.am                               |   2 +
 kdesktop/desktop.cc                                |  47 ++
 kdesktop/desktop.h                                 |   5 +
 kdesktop/kdiconview.cc                             | 120 +++-
 kdesktop/kdiconview.h                              |   9 +-
 kdesktop/lock/lockprocess.cc                       | 244 +++++++-
 kdesktop/lock/lockprocess.h                        |  30 +-
 kdesktop/minicli.cpp                               |  15 +-
 kdesktop/minicli.h                                 |   4 +-
 kdesu/kdesu/kdesu.cpp                              |   1 +
 kdesu/kdesud/kdesud.cpp                            |   3 +
 kdm/backend/client.c                               |  93 ++-
 kdm/config.def                                     |  11 +
 kdm/configure.in.in                                |  71 +++
 kdm/kfrontend/Makefile.am                          |   1 +
 kdm/kfrontend/kdm_greet.c                          |   2 +-
 kdm/kfrontend/kdmadmindialog.cpp                   | 176 ++++++
 kdm/kfrontend/kdmadmindialog.h                     |  70 +++
 kdm/kfrontend/kdmconfig.cpp                        |   2 +
 kdm/kfrontend/kdmconfig.h                          |  14 +
 kdm/kfrontend/kfdialog.cpp                         |   4 +
 kdm/kfrontend/kgapp.cpp                            |   5 +
 kdm/kfrontend/kgdialog.cpp                         |   4 +-
 kdm/kfrontend/kgreeter.cpp                         | 214 ++++++-
 kdm/kfrontend/kgreeter.h                           |   9 +-
 kdm/kfrontend/sessions/Makefile.am                 |   2 +-
 kdm/kfrontend/sessions/admin.desktop               |   7 +
 kdm/kfrontend/themer/kdmitem.cpp                   | 107 +++-
 kdm/kfrontend/themer/kdmitem.h                     |   7 +
 kdm/kfrontend/themer/kdmlabel.cpp                  |  67 ++-
 kdm/kfrontend/themer/kdmlabel.h                    |   6 +
 kdm/kfrontend/themer/kdmlayout.cpp                 |   9 +-
 kdm/kfrontend/themer/kdmpixmap.cpp                 |  98 ++-
 kdm/kfrontend/themer/kdmpixmap.h                   |   5 +-
 kdm/kfrontend/themer/kdmrect.cpp                   |  32 +-
 kdm/kfrontend/themer/kdmrect.h                     |   4 +-
 kdm/kfrontend/themer/kdmthemer.cpp                 |  73 ++-
 kdm/kfrontend/themer/kdmthemer.h                   |   4 +
 kdmlib/Makefile.am                                 |   6 +-
 kdmlib/kgreet_pam.cpp                              | 668 +++++++++++++++++++++
 kdmlib/kgreet_pam.h                                |  93 +++
 khelpcenter/kcmhelpcenter.cpp                      |   7 +
 khelpcenter/kcmhelpcenter.h                        |   5 +
 khelpcenter/navigator.cpp                          |  10 +-
 khelpcenter/searchhandlers/Makefile.am             |   2 +-
 khelpcenter/searchhandlers/docbook.desktop         |   4 +-
 khelpcenter/searchhandlers/khc_beagle_index.pl     |  49 ++
 khelpcenter/searchhandlers/khc_beagle_search.pl    |  88 +++
 kicker/applets/systemtray/systemtrayapplet.cpp     |  98 ++-
 kicker/applets/systemtray/systemtrayapplet.h       |   1 +
 .../data/kickoff/button-box-gradient-topdown.png   | Bin 0 -> 213 bytes
 kicker/data/kickoff/button-box-gradient.png        | Bin 0 -> 255 bytes
 kicker/data/kickoff/button-box-left-corner.png     | Bin 0 -> 203 bytes
 kicker/data/kickoff/button-box-left.png            | Bin 0 -> 306 bytes
 kicker/data/kickoff/button-box-right-corner.png    | Bin 0 -> 214 bytes
 kicker/data/kickoff/button-box-top.png             | Bin 0 -> 163 bytes
 kicker/data/kickoff/cr128-action-suspend2disk.png  | Bin 0 -> 13797 bytes
 kicker/data/kickoff/cr128-action-suspend2ram.png   | Bin 0 -> 15500 bytes
 kicker/data/kickoff/cr16-action-suspend2disk.png   | Bin 0 -> 834 bytes
 kicker/data/kickoff/cr16-action-suspend2ram.png    | Bin 0 -> 865 bytes
 kicker/data/kickoff/cr32-action-leave.png          | Bin 0 -> 1602 bytes
 kicker/data/kickoff/cr32-action-suspend2disk.png   | Bin 0 -> 2091 bytes
 kicker/data/kickoff/cr32-action-suspend2ram.png    | Bin 0 -> 2243 bytes
 kicker/data/kickoff/cr48-action-leave.png          | Bin 0 -> 2475 bytes
 kicker/data/kickoff/cr48-action-suspend2disk.png   | Bin 0 -> 3713 bytes
 kicker/data/kickoff/cr48-action-suspend2ram.png    | Bin 0 -> 3965 bytes
 kicker/data/kickoff/cr48-app-recently_used.png     | Bin 0 -> 4736 bytes
 kicker/data/kickoff/cr64-action-suspend2disk.png   | Bin 0 -> 5601 bytes
 kicker/data/kickoff/cr64-action-suspend2ram.png    | Bin 0 -> 6115 bytes
 kicker/data/kickoff/crsc-action-leave.svgz         | Bin 0 -> 3915 bytes
 kicker/data/kickoff/crsc-action-suspend2disk.svgz  | Bin 0 -> 12713 bytes
 kicker/data/kickoff/crsc-action-suspend2ram.svgz   | Bin 0 -> 13613 bytes
 kicker/data/kickoff/kmenu_active.png               | Bin 0 -> 3257 bytes
 kicker/data/kickoff/kmenu_basic.mng                | Bin 0 -> 81101 bytes
 kicker/data/kickoff/kmenu_flipped.mng              | Bin 0 -> 81240 bytes
 kicker/data/kickoff/kmenu_vertical.mng             | Bin 0 -> 62006 bytes
 kicker/data/kickoff/left_triangle.png              | Bin 0 -> 781 bytes
 kicker/data/kickoff/main_border_bc.png             | Bin 0 -> 171 bytes
 kicker/data/kickoff/main_border_lc.png             | Bin 0 -> 166 bytes
 kicker/data/kickoff/main_border_rc.png             | Bin 0 -> 174 bytes
 kicker/data/kickoff/main_border_tc.png             | Bin 0 -> 163 bytes
 kicker/data/kickoff/main_corner_bl.png             | Bin 0 -> 211 bytes
 kicker/data/kickoff/main_corner_br.png             | Bin 0 -> 218 bytes
 kicker/data/kickoff/main_corner_tl.png             | Bin 0 -> 176 bytes
 kicker/data/kickoff/main_corner_tr.png             | Bin 0 -> 202 bytes
 kicker/data/kickoff/menu_separator.png             | Bin 0 -> 260 bytes
 kicker/data/kickoff/resize_handle.png              | Bin 0 -> 217 bytes
 kicker/data/kickoff/right_triangle.png             | Bin 0 -> 722 bytes
 kicker/data/kickoff/search-gradient-topdown.png    | Bin 0 -> 181 bytes
 kicker/data/kickoff/search-gradient.png            | Bin 0 -> 218 bytes
 kicker/data/kickoff/search-running.mng             | Bin 0 -> 11888 bytes
 kicker/data/kickoff/search-tab-center.png          | Bin 0 -> 170 bytes
 kicker/data/kickoff/search-tab-left.png            | Bin 0 -> 398 bytes
 kicker/data/kickoff/search-tab-right.png           | Bin 0 -> 417 bytes
 kicker/data/kickoff/search-tab-top-center.png      | Bin 0 -> 146 bytes
 kicker/data/kickoff/search-tab-top-left.png        | Bin 0 -> 2960 bytes
 kicker/data/kickoff/search-tab-top-right.png       | Bin 0 -> 368 bytes
 kicker/data/kickoff/tab-bottom-left-topdown.png    | Bin 0 -> 145 bytes
 kicker/data/kickoff/tab-bottom-left.png            | Bin 0 -> 304 bytes
 kicker/data/kickoff/tab-bottom-right-topdown.png   | Bin 0 -> 171 bytes
 kicker/data/kickoff/tab-bottom-right.png           | Bin 0 -> 351 bytes
 kicker/data/kickoff/tab-center-topdown.png         | Bin 0 -> 142 bytes
 kicker/data/kickoff/tab-center.png                 | Bin 0 -> 175 bytes
 kicker/data/kickoff/tab-left_center.png            | Bin 0 -> 165 bytes
 kicker/data/kickoff/tab-right_center.png           | Bin 0 -> 165 bytes
 kicker/data/kickoff/tab-top-left-topdown.png       | Bin 0 -> 256 bytes
 kicker/data/kickoff/tab-top-left.png               | Bin 0 -> 198 bytes
 kicker/data/kickoff/tab-top-right-topdown.png      | Bin 0 -> 327 bytes
 kicker/data/kickoff/tab-top-right.png              | Bin 0 -> 198 bytes
 kicker/kicker/ui/browser_mnu.cpp                   |   9 +-
 kicker/kicker/ui/service_mnu.cpp                   | 123 +++-
 kicker/kicker/ui/service_mnu.h                     |   3 +-
 kicker/libkicker/kickerSettings.kcfg               |   5 +
 kioslave/media/mediaimpl.cpp                       |   7 +
 kioslave/media/mediamanager/halbackend.cpp         |   8 +
 kioslave/smb/kio_smb_auth.cpp                      |   1 +
 kioslave/system/entries/documents.desktop          |   2 +-
 klipper/klipperrc.desktop                          |   4 +-
 konqueror/Makefile.am                              |   4 +-
 konqueror/konq_combo.cc                            |  12 +
 konqueror/konq_combo.h                             |   1 +
 konqueror/konq_frame.cc                            |   5 +
 konsole/other/x11r5.keytab                         |   4 +-
 kscreensaver/Makefile.am                           |   4 +-
 kscreensaver/random.cpp                            | 102 +++-
 ksmserver/KSMServerInterface.h                     |   2 +
 ksmserver/Makefile.am                              |   4 +-
 ksmserver/server.h                                 |  12 +
 ksmserver/shutdown.cpp                             |  78 ++-
 ksmserver/shutdowndlg.cpp                          |  70 ++-
 ksmserver/shutdowndlg.h                            |  19 +
 ksmserver/test.cpp                                 |   7 +-
 ksmserver/timed.ui                                 | 352 +++++++++++
 kwin/workspace.cpp                                 |  14 +
 kxkb/kcmlayout.cpp                                 |   3 +
 nsplugins/nspluginloader.cpp                       |   6 +-
 nsplugins/nspluginloader.h                         |   2 +-
 nsplugins/pluginscan.cpp                           |   2 +-
 145 files changed, 3334 insertions(+), 251 deletions(-)
 create mode 100644 kdm/kfrontend/kdmadmindialog.cpp
 create mode 100644 kdm/kfrontend/kdmadmindialog.h
 create mode 100644 kdm/kfrontend/sessions/admin.desktop
 create mode 100644 kdmlib/kgreet_pam.cpp
 create mode 100644 kdmlib/kgreet_pam.h
 create mode 100644 khelpcenter/searchhandlers/khc_beagle_index.pl
 create mode 100644 khelpcenter/searchhandlers/khc_beagle_search.pl
 create mode 100644 kicker/data/kickoff/button-box-gradient-topdown.png
 create mode 100644 kicker/data/kickoff/button-box-gradient.png
 create mode 100644 kicker/data/kickoff/button-box-left-corner.png
 create mode 100644 kicker/data/kickoff/button-box-left.png
 create mode 100644 kicker/data/kickoff/button-box-right-corner.png
 create mode 100644 kicker/data/kickoff/button-box-top.png
 create mode 100644 kicker/data/kickoff/cr128-action-suspend2disk.png
 create mode 100644 kicker/data/kickoff/cr128-action-suspend2ram.png
 create mode 100644 kicker/data/kickoff/cr16-action-suspend2disk.png
 create mode 100644 kicker/data/kickoff/cr16-action-suspend2ram.png
 create mode 100644 kicker/data/kickoff/cr32-action-leave.png
 create mode 100644 kicker/data/kickoff/cr32-action-suspend2disk.png
 create mode 100644 kicker/data/kickoff/cr32-action-suspend2ram.png
 create mode 100644 kicker/data/kickoff/cr48-action-leave.png
 create mode 100644 kicker/data/kickoff/cr48-action-suspend2disk.png
 create mode 100644 kicker/data/kickoff/cr48-action-suspend2ram.png
 create mode 100644 kicker/data/kickoff/cr48-app-recently_used.png
 create mode 100644 kicker/data/kickoff/cr64-action-suspend2disk.png
 create mode 100644 kicker/data/kickoff/cr64-action-suspend2ram.png
 create mode 100644 kicker/data/kickoff/crsc-action-leave.svgz
 create mode 100644 kicker/data/kickoff/crsc-action-suspend2disk.svgz
 create mode 100644 kicker/data/kickoff/crsc-action-suspend2ram.svgz
 create mode 100644 kicker/data/kickoff/kmenu_active.png
 create mode 100644 kicker/data/kickoff/kmenu_basic.mng
 create mode 100644 kicker/data/kickoff/kmenu_flipped.mng
 create mode 100644 kicker/data/kickoff/kmenu_vertical.mng
 create mode 100644 kicker/data/kickoff/left_triangle.png
 create mode 100644 kicker/data/kickoff/main_border_bc.png
 create mode 100644 kicker/data/kickoff/main_border_lc.png
 create mode 100644 kicker/data/kickoff/main_border_rc.png
 create mode 100644 kicker/data/kickoff/main_border_tc.png
 create mode 100644 kicker/data/kickoff/main_corner_bl.png
 create mode 100644 kicker/data/kickoff/main_corner_br.png
 create mode 100644 kicker/data/kickoff/main_corner_tl.png
 create mode 100644 kicker/data/kickoff/main_corner_tr.png
 create mode 100644 kicker/data/kickoff/menu_separator.png
 create mode 100644 kicker/data/kickoff/resize_handle.png
 create mode 100644 kicker/data/kickoff/right_triangle.png
 create mode 100644 kicker/data/kickoff/search-gradient-topdown.png
 create mode 100644 kicker/data/kickoff/search-gradient.png
 create mode 100644 kicker/data/kickoff/search-running.mng
 create mode 100644 kicker/data/kickoff/search-tab-center.png
 create mode 100644 kicker/data/kickoff/search-tab-left.png
 create mode 100644 kicker/data/kickoff/search-tab-right.png
 create mode 100644 kicker/data/kickoff/search-tab-top-center.png
 create mode 100644 kicker/data/kickoff/search-tab-top-left.png
 create mode 100644 kicker/data/kickoff/search-tab-top-right.png
 create mode 100644 kicker/data/kickoff/tab-bottom-left-topdown.png
 create mode 100644 kicker/data/kickoff/tab-bottom-left.png
 create mode 100644 kicker/data/kickoff/tab-bottom-right-topdown.png
 create mode 100644 kicker/data/kickoff/tab-bottom-right.png
 create mode 100644 kicker/data/kickoff/tab-center-topdown.png
 create mode 100644 kicker/data/kickoff/tab-center.png
 create mode 100644 kicker/data/kickoff/tab-left_center.png
 create mode 100644 kicker/data/kickoff/tab-right_center.png
 create mode 100644 kicker/data/kickoff/tab-top-left-topdown.png
 create mode 100644 kicker/data/kickoff/tab-top-left.png
 create mode 100644 kicker/data/kickoff/tab-top-right-topdown.png
 create mode 100644 kicker/data/kickoff/tab-top-right.png
 create mode 100644 ksmserver/timed.ui

diff --git a/kcheckpass/checkpass_pam.c b/kcheckpass/checkpass_pam.c
index 6f281165f..44758b696 100644
--- a/kcheckpass/checkpass_pam.c
+++ b/kcheckpass/checkpass_pam.c
@@ -140,13 +140,16 @@ AuthReturn Authenticate(const char *caller, const char *method,
   openlog("kcheckpass", LOG_PID, LOG_AUTH);
 
   PAM_data.conv = conv;
-  if (strcmp(method, "classic")) {
-    sprintf(pservb, "%.31s-%.31s", caller, method);
-    pam_service = pservb;
-  } else {
+  if (!strcmp(method, "classic")) {
     PAM_data.classic = 1;
     pam_service = caller;
   }
+  else if (!strcmp(method, "pam")) {
+    pam_service = caller;
+  } else {
+    sprintf(pservb, "%.31s-%.31s", caller, method);
+    pam_service = pservb;
+  }
   pam_error = pam_start(pam_service, user, &PAM_conversation, &pamh);
   if (pam_error != PAM_SUCCESS)
     return AuthError;
diff --git a/kcontrol/background/bgdialog.cpp b/kcontrol/background/bgdialog.cpp
index ae76b701a..8294f53a3 100644
--- a/kcontrol/background/bgdialog.cpp
+++ b/kcontrol/background/bgdialog.cpp
@@ -504,14 +504,23 @@ void BGDialog::loadWallpaperFilesList() {
    //search for .desktop files before searching for images without .desktop files
    TQStringList lst = m_pDirs->findAllResources("wallpaper", "*desktop", false, true);
    TQStringList files;
+   TQStringList hiddenfiles;
    for (TQStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it)
    {
       KSimpleConfig fileConfig(*it);
       fileConfig.setGroup("Wallpaper");
 
+      int slash = (*it).findRev('/') + 1;
+      TQString directory = (*it).left(slash);
+      
       TQString imageCaption = fileConfig.readEntry("Name");
       TQString fileName = fileConfig.readEntry("File");
 
+      if (fileConfig.readBoolEntry("Hidden",false)) {
+         hiddenfiles.append(directory + fileName);
+         continue;
+      }
+      
       if (imageCaption.isEmpty())
       {
          imageCaption = fileName;
@@ -527,9 +536,8 @@ void BGDialog::loadWallpaperFilesList() {
          rs = imageCaption + " (" + TQString::number(n) + ')';
          lrs = rs.lower();
       }
-      int slash = (*it).findRev('/') + 1;
-      TQString directory = (*it).left(slash);
       bool canLoadScaleable = false;
+
 #ifdef HAVE_LIBART
       canLoadScaleable = true;
 #endif
@@ -543,7 +551,7 @@ void BGDialog::loadWallpaperFilesList() {
    lst = m_pDirs->findAllResources("wallpaper", "*", false, true);
    for (TQStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it)
    {
-      if ( !(*it).endsWith(".desktop") && files.grep(*it).empty() ) {
+      if ( !(*it).endsWith(".desktop") && files.grep(*it).empty() && hiddenfiles.grep(*it).empty() ) {
          // First try to see if we have a comment describing the image.  If we do
          // just use the first line of said comment.
          KFileMetaInfo metaInfo(*it);
diff --git a/kcontrol/input/xcursor/themepage.cpp b/kcontrol/input/xcursor/themepage.cpp
index 4fb8b8a69..7caf18c3f 100644
--- a/kcontrol/input/xcursor/themepage.cpp
+++ b/kcontrol/input/xcursor/themepage.cpp
@@ -73,6 +73,13 @@ struct ThemeInfo {
 };
 
 
+static TQString defaultThemeDescription( const TQString& theme )
+{
+    if( theme == "redglass" || theme == "whiteglass" || theme == "pseudocore" || theme == "handhelds" )
+        return i18n( "XFree theme %1 - incomplete for KDE" ).arg( theme );
+    return i18n( "No description available" );;
+}
+
 ThemePage::ThemePage( TQWidget* parent, const char* name )
 	: TQWidget( parent, name ), selectedTheme( NULL ), currentTheme( NULL )
 {
@@ -333,7 +340,7 @@ void ThemePage::insertTheme( const TQString &path )
 
 	// Defaults in case there's no name or comment field.
 	TQString name   = dirName;
-	TQString desc   = i18n( "No description available" );
+	TQString desc   = defaultThemeDescription( name );
 	TQString sample = "left_ptr";
 
 	KSimpleConfig c( path + "/index.theme", true ); // Open read-only
@@ -480,7 +487,7 @@ void ThemePage::insertThemes()
 			// Defaults in case there's no index.theme file or it lacks
 			// a name and a comment field.
 			TQString name   = *it;
-			TQString desc   = i18n( "No description available" );
+			TQString desc   = defaultThemeDescription( name );
 			TQString sample = "left_ptr";
 
 			// Parse the index.theme file if the theme has one.
diff --git a/kcontrol/kicker/menutab_impl.h b/kcontrol/kicker/menutab_impl.h
index 3d0e09748..877e47ffe 100644
--- a/kcontrol/kicker/menutab_impl.h
+++ b/kcontrol/kicker/menutab_impl.h
@@ -19,6 +19,9 @@
 #define __menutab_impl_h__
 
 #include <tqlistview.h>
+#include <stdlib.h>
+
+#include <kpushbutton.h>
 
 #include "menutab.h"
 
diff --git a/kcontrol/spellchecking/spellchecking.cpp b/kcontrol/spellchecking/spellchecking.cpp
index 6416f9e9c..a7ed79b46 100644
--- a/kcontrol/spellchecking/spellchecking.cpp
+++ b/kcontrol/spellchecking/spellchecking.cpp
@@ -67,7 +67,7 @@ void KSpellCheckingConfig::defaults()
     spellConfig->setRunTogether(0);
     spellConfig->setDictionary("");
     spellConfig->setDictFromList(FALSE);
-    spellConfig->setEncoding (KS_E_ASCII);
+    spellConfig->setEncoding (KS_E_UTF8);
     spellConfig->setClient (KS_CLIENT_ISPELL);
 }
 
diff --git a/kdeeject/kdeeject b/kdeeject/kdeeject
index 71079794d..34e61097e 100755
--- a/kdeeject/kdeeject
+++ b/kdeeject/kdeeject
@@ -4,12 +4,38 @@
 #
 # Copyright GPL v2 by David Faure <david@mandrakesoft.com>
 #
-if test $# -ge 1 -a "$1" != "--help"; then
-  quiet=0
-  if test "$1" = "-q"; then
-    quiet=1
-    shift
-  fi
+quiet=0
+if test "$1" = "-q"; then
+  quiet=1
+  shift
+fi
+
+if test "$1" = "--help"; then
+   echo "Usage: $0 <name> where name is a device or a mountpoint."
+   exit 0
+fi
+
+if test -z "$1"; then
+  for dev in /dev/cdrom /dev/dvd /dev/dvdram /dev/cdrecorder; do
+     if test -e $dev; then
+        lp=`readlink $dev`
+	if test -n "$lp"; then
+	    device=/dev/$lp
+	else
+	    device=$dev
+        fi
+        break
+    fi
+  done
+else
+  device=$1
+fi
+
+udi=`dcop kded mediamanager properties $device 2>/dev/null | head -n 1 `
+if test -n "$udi"; then
+    dcop kded mediamanager unmount "$udi" >/dev/null 2>&1
+fi
+
   # Checking for stuff in the PATH is ugly with sh.
   # I guess this is the reason for making this a kde app...
   OS=`uname -s`
@@ -34,7 +60,5 @@ if test $# -ge 1 -a "$1" != "--help"; then
   elif test $quiet -eq 0; then
     kdialog --title "KDE Eject" --error "Eject $1 failed!"
   fi
-else
-  kdialog --title "KDE Eject" --msgbox "Usage: $0 <name> where name is a device or a mountpoint."
-fi
+
 exit 1
diff --git a/kdesktop/KDesktopIface.h b/kdesktop/KDesktopIface.h
index 1aa90e538..b966405e4 100644
--- a/kdesktop/KDesktopIface.h
+++ b/kdesktop/KDesktopIface.h
@@ -107,6 +107,35 @@ k_dcop:
      * space for desktop icons
      */
     virtual void desktopIconsAreaChanged(const TQRect &area, int screen) = 0;
+
+    /**
+     * Find the next free place for a not yet existing icon, so it fits
+     * in the user arrangement. Basicly prepare for icons to be moved in.
+     * It will try to find a place in the virtual grid near col,row
+     * where no other icon is.
+     *
+     * If you specify -1 for row or column, it will try to find the next
+     * free room where no other icon follows. E.g. if you specify column
+     * = -1 and row = 0, kdesktop will find the next vertical placement
+     * so that the icon appears at the end of the existing icons preferable
+     * in the first column. If the first column is full, it will find the
+     * next free room in the second column.
+     *
+     * If you specify both column and row, kdesktop won't care for aligning,
+     * or surrounding icons, but try to find the free place near the given
+     * grid place (e.g. specify 0,0 to find the nearest place in the left
+     * upper corner).
+     */
+    virtual TQPoint findPlaceForIcon( int column, int row) = 0;
+
+    /// copy the desktop file in the Desktop and place it at x, y
+    virtual void addIcon(const TQString &url, int x, int y) = 0;
+
+    /// same with specific destination
+    virtual void addIcon(const TQString &url, const TQString &dest, int x, int y) = 0;
+
+    /// remove the desktop file (either full path or relative)
+    virtual void removeIcon(const TQString &dest) = 0;
 };
 
 #endif
diff --git a/kdesktop/Makefile.am b/kdesktop/Makefile.am
index fecd9e9c4..5035fe77f 100644
--- a/kdesktop/Makefile.am
+++ b/kdesktop/Makefile.am
@@ -6,6 +6,8 @@ kdesktop_la_LIBADD   = libkdesktopsettings.la $(top_builddir)/libkonq/libkonq.la
 
 SUBDIRS = . lock pics patterns programs init kwebdesktop
 
+KDE_OPTIONS = nofinal
+
 ####### Files
 
 bin_PROGRAMS = kcheckrunning
diff --git a/kdesktop/desktop.cc b/kdesktop/desktop.cc
index 54513e962..a05dfcb99 100644
--- a/kdesktop/desktop.cc
+++ b/kdesktop/desktop.cc
@@ -32,6 +32,9 @@
 #include <unistd.h>
 #include <kcolordrag.h>
 #include <kurldrag.h>
+#include <stdlib.h>
+#include <kio/job.h>
+#include <tqfile.h>
 
 #include <tqdir.h>
 #include <tqevent.h>
@@ -58,6 +61,7 @@
 #include <kglobalsettings.h>
 #include <kpopupmenu.h>
 #include <kapplication.h>
+#include <kdirlister.h>
 // Create the equivalent of KAccelBase::connectItem
 // and then remove this include and fix reconnects in initRoot() -- ellis
 //#include <kaccelbase.h>
@@ -986,4 +990,47 @@ bool KDesktop::event(TQEvent * e)
     return TQWidget::event(e);
 }
 
+TQPoint KDesktop::findPlaceForIcon( int column, int row )
+{
+    if (m_pIconView)
+        return m_pIconView->findPlaceForIcon(column, row);
+    else
+        return TQPoint(-1, -1);
+}
+
+void KDesktop::addIcon(const TQString & _url, int x, int y)
+{
+    addIcon( _url, KGlobalSettings::desktopPath(), x, y );
+}
+
+void KDesktop::addIcon(const TQString & _url, const TQString & _dest, int x, int y)
+{
+    TQString filename = _url.mid(_url.findRev('/') + 1);
+
+    TQValueList<KIO::CopyInfo> files;
+    KIO::CopyInfo i;
+    i.uSource = KURL::fromPathOrURL( _url );
+    i.uDest   = KURL::fromPathOrURL( _dest );
+    i.uDest.addPath( filename );
+    files.append(i);
+    if (!TQFile::exists(i.uDest.prettyURL().replace("file://",TQString::null))) { m_pIconView->slotAboutToCreate( TQPoint( x, y ), files );
+    KIO::copy( i.uSource, i.uDest, false ); }
+
+//    m_pIconView->addFuturePosition(filename, x, y);
+    // qDebug("addIcon %s %s %d %d", _url.latin1(), _dest.latin1(), x, y);
+//    system(TQString("cp \"%1\" \"%2/%3\"").arg(KURL(_url).path()).arg(KURL(_dest).path()).arg(filename).latin1());
+//    m_pIconView->update( _dest );
+}
+
+void KDesktop::removeIcon(const TQString &_url)
+{
+	if (_url.at(0) != '/') {
+		qDebug("removeIcon with relative path not supported for now");
+		return;
+	}
+	unlink(KURL(_url).path().latin1());
+	TQString dest = _url.left(_url.findRev('/') + 1);
+        m_pIconView->update( dest );
+}
+
 #include "desktop.moc"
diff --git a/kdesktop/desktop.h b/kdesktop/desktop.h
index d8ec12c69..31928e9d4 100644
--- a/kdesktop/desktop.h
+++ b/kdesktop/desktop.h
@@ -164,6 +164,11 @@ protected:
   virtual void setIconsEnabled( bool enable );
   virtual bool event ( TQEvent * e );
 
+  virtual TQPoint findPlaceForIcon( int column, int row);
+  virtual void addIcon(const TQString &url, int x, int y);
+  virtual void addIcon(const TQString &url, const TQString &dest, int x, int y);
+  virtual void removeIcon(const TQString &url);
+
 private slots:
   void desktopResized();
 
diff --git a/kdesktop/kdiconview.cc b/kdesktop/kdiconview.cc
index caa68feb9..5762458fd 100644
--- a/kdesktop/kdiconview.cc
+++ b/kdesktop/kdiconview.cc
@@ -962,6 +962,18 @@ void KDIconView::slotNewItems( const KFileItemList & entries )
   kdDebug(1214) << "KDIconView::slotNewItems count=" << entries.count() << endl;
   KFileItemListIterator it(entries);
   KFileIVI* fileIVI = 0L;
+
+  if (m_nextItemPos.isNull() && !m_dotDirectory)  {
+      // Not found, we'll need to save the new pos
+      kdDebug(1214)<<"Neither a  drop position stored nor m_dotDirectory set"<<endl;
+      m_dotDirectory = new KSimpleConfig( dotDirectoryPath(), true );
+      // recursion
+      slotNewItems( entries );
+      delete m_dotDirectory;
+      m_dotDirectory = 0;
+      return;
+  }
+
   for (; it.current(); ++it)
   {
     KURL url = it.current()->url();
@@ -1026,15 +1038,6 @@ void KDIconView::slotNewItems( const KFileItemList & entries )
             kdDebug(1214)<<"Using saved position"<<endl;
         }
       }
-      else
-      {
-            // Not found, we'll need to save the new pos
-            kdDebug(1214)<<"slotNewItems(): New item without position information, try to find a sane location"<<endl;
-
-            moveToFreePosition(fileIVI);
-
-            m_bNeedSave = true;
-      }
     }
   }
 
@@ -1638,6 +1641,98 @@ void KDIconView::moveToFreePosition(TQIconViewItem *item )
 }
 
 
+TQPoint KDIconView::findPlaceForIconCol( int column, int dx, int dy)
+{
+    if (column < 0)
+        return TQPoint();
+
+    TQRect rect;
+    rect.moveTopLeft( TQPoint(column * dx, 0) );
+    rect.setWidth(dx);
+    rect.setHeight(dy);
+
+    if (rect.right() > viewport()->width())
+        return TQPoint();
+
+    while ( rect.bottom() < viewport()->height() - spacing() )
+    {
+        if ( !isFreePosition(0,rect) )
+            rect.moveBy(0, rect.height());
+        else
+            return rect.topLeft();
+    }
+
+    return TQPoint();
+}
+
+TQPoint KDIconView::findPlaceForIconRow( int row, int dx, int dy )
+{
+    if (row < 0)
+        return TQPoint();
+
+    TQRect rect;
+    rect.moveTopLeft(TQPoint(0, row * dy));
+    rect.setWidth(dx);
+    rect.setHeight(dy);
+
+    if (rect.bottom() > viewport()->height())
+        return TQPoint();
+
+    while (rect.right() < viewport()->width() - spacing())
+    {
+        if (!isFreePosition(0,rect))
+            rect.moveBy(rect.width()+spacing(), 0);
+        else
+            return rect.topLeft();
+    }
+
+    return TQPoint();
+}
+
+TQPoint KDIconView::findPlaceForIcon( int column, int row)
+{
+    int dx = gridXValue(), dy = 0;
+    TQIconViewItem *item = firstItem();
+    for ( ; item; item = item->nextItem() ) {
+        dx = QMAX( dx, item->width() );
+        dy = QMAX( dy, item->height() );
+    }
+
+    dx += spacing();
+    dy += spacing();
+
+    if (row == -1) {
+        int max_cols = viewport()->width() / dx;
+        int delta = 0;
+        TQPoint res;
+        do {
+            delta++;
+            res = findPlaceForIconCol(column + (delta / 2) * (-2 * (delta % 2) + 1),
+                                      dx, dy);
+            if (delta / 2 > QMAX(max_cols - column, column))
+                return res;
+        } while (res.isNull());
+        return res;
+    }
+
+    if (column == -1) {
+        int max_rows = viewport()->height() / dy;
+        int delta = 0;
+        TQPoint res;
+        do {
+            delta++;
+            res = findPlaceForIconRow(row + (delta / 2) * (-2 * (delta % 2) + 1),
+                                      dx, dy);
+            if (delta / 2 > QMAX(max_rows - row, row))
+                return res;
+        } while (res.isNull());
+        return res;
+    }
+
+    // very unlikely - if I may add that
+    return TQPoint(0, 0);
+}
+
 void KDIconView::saveIconPositions()
 {
   kdDebug(1214) << "KDIconView::saveIconPositions" << endl;
@@ -1665,4 +1760,11 @@ void KDIconView::saveIconPositions()
   m_dotDirectory->sync();
 }
 
+void KDIconView::update( const TQString &_url )
+{
+	if (m_dirLister)
+		m_dirLister->updateDirectory( _url );
+}
+
+
 #include "kdiconview.moc"
diff --git a/kdesktop/kdiconview.h b/kdesktop/kdiconview.h
index 715a0eb5e..5ef349322 100644
--- a/kdesktop/kdiconview.h
+++ b/kdesktop/kdiconview.h
@@ -73,6 +73,8 @@ public:
 
     TQStringList selectedURLs();
 
+    void update( const TQString &url );
+
     /**
      * Save the icon positions
      */
@@ -103,6 +105,10 @@ public:
 
     void startDirLister();
 
+    TQPoint findPlaceForIconCol( int column, int dx, int dy );
+    TQPoint findPlaceForIconRow( int row, int dx, int dy );
+    TQPoint findPlaceForIcon( int column, int row );
+
 protected slots:
 
     // slots connected to the icon view
@@ -112,8 +118,9 @@ protected slots:
     void slotMouseButtonClickedKDesktop(int _button, TQIconViewItem* _item, const TQPoint& _global);
     void slotContextMenuRequested(TQIconViewItem* _item, const TQPoint& _global);
     void slotEnableAction( const char * name, bool enabled );
+public slots:
     void slotAboutToCreate(const TQPoint &pos, const TQValueList<KIO::CopyInfo> &files);
-
+protected slots:
     void slotItemRenamed(TQIconViewItem*, const TQString &name);
 
     // slots connected to the directory lister
diff --git a/kdesktop/lock/lockprocess.cc b/kdesktop/lock/lockprocess.cc
index d589232a1..cdd5581e7 100644
--- a/kdesktop/lock/lockprocess.cc
+++ b/kdesktop/lock/lockprocess.cc
@@ -39,6 +39,8 @@
 #include <kstdguiitem.h>
 #include <kpixmapeffect.h>
 #include <kpixmap.h>
+#include <kwin.h>
+#include <kwinmodule.h>
 
 #include <tqframe.h>
 #include <tqlabel.h>
@@ -119,6 +121,8 @@ static void segv_handler(int)
 	sleep(1);
 }
 
+extern Atom qt_wm_state;
+
 //===========================================================================
 //
 // Screen saver handling process.  Handles screensaver window,
@@ -135,6 +139,8 @@ LockProcess::LockProcess(bool child, bool useBlankOnly)
       mRestoreXF86Lock(false),
       mForbidden(false),
       mAutoLogout(false),
+      mVkbdProcess(NULL),
+      mKWinModule(NULL),
       mPipeOpen(false),
       mPipeOpen_out(false),
       mInfoMessageDisplayed(false),
@@ -1120,9 +1126,11 @@ bool LockProcess::checkPass()
         if (mAutoLogout)
             killTimer(mAutoLogoutTimerId);
 
+        showVkbd();
         PasswordDlg passDlg( this, &greetPlugin);
-
         int ret = execDialog( &passDlg );
+        hideVkbd();
+
         if (mForceReject == true) {
             ret = TQDialog::Rejected;
         }
@@ -1251,9 +1259,13 @@ bool LockProcess::x11Event(XEvent *event)
 
     switch (event->type)
     {
-        case KeyPress:
         case ButtonPress:
         case MotionNotify:
+        case ButtonRelease:
+            if( forwardVkbdEvent( event ))
+                return true; // filter out
+            // fall through
+        case KeyPress:
             if (mBusy || !mDialogs.isEmpty())
                 break;
             mBusy = true;
@@ -1290,11 +1302,30 @@ bool LockProcess::x11Event(XEvent *event)
         case ConfigureNotify: // from SubstructureNotifyMask on the root window
             if(event->xconfigure.event == qt_xrootwin())
                 stayOnTop();
+            for( TQValueList< VkbdWindow >::Iterator it = mVkbdWindows.begin();
+                 it != mVkbdWindows.end();
+                 ++it ) {
+                if( (*it).id == event->xconfigure.window ) {
+                    (*it).rect = TQRect( event->xconfigure.x, event->xconfigure.y,
+                        event->xconfigure.width, event->xconfigure.height );
+                    break;
+                }
+            }
             break;
         case MapNotify: // from SubstructureNotifyMask on the root window
+            windowAdded( event->xmap.window, false );
             if( event->xmap.event == qt_xrootwin())
                 stayOnTop();
             break;
+        case DestroyNotify:
+            for( TQValueList< VkbdWindow >::Iterator it = mVkbdWindows.begin();
+                 it != mVkbdWindows.end();
+                 ++it )
+                if( (*it).id == event->xdestroywindow.window ) {
+                    mVkbdWindows.remove( it );
+                    break;
+            }
+            break;
     }
 
     // We have grab with the grab window being the root window.
@@ -1319,17 +1350,24 @@ bool LockProcess::x11Event(XEvent *event)
 
 void LockProcess::stayOnTop()
 {
-    if(!mDialogs.isEmpty())
+    if(!mDialogs.isEmpty() || !mVkbdWindows.isEmpty())
     {
         // this restacking is written in a way so that
         // if the stacking positions actually don't change,
         // all restacking operations will be no-op,
         // and no ConfigureNotify will be generated,
         // thus avoiding possible infinite loops
-        XRaiseWindow( qt_xdisplay(), mDialogs.first()->winId()); // raise topmost
+        if( !mVkbdWindows.isEmpty())
+            XRaiseWindow( qt_xdisplay(), mVkbdWindows.first().id );
+        else
+            XRaiseWindow( qt_xdisplay(), mDialogs.first()->winId()); // raise topmost
         // and stack others below it
-        Window* stack = new Window[ mDialogs.count() + 1 ];
+        Window* stack = new Window[ mDialogs.count() + mVkbdWindows.count() + 1 ];
         int count = 0;
+        for( TQValueList< VkbdWindow >::ConstIterator it = mVkbdWindows.begin();
+             it != mVkbdWindows.end();
+             ++it )
+            stack[ count++ ] = (*it).id;
         for( TQValueList< TQWidget* >::ConstIterator it = mDialogs.begin();
              it != mDialogs.end();
              ++it )
@@ -1428,4 +1466,200 @@ void LockProcess::msgBox( TQMessageBox::Icon type, const TQString &txt )
     execDialog( &box );
 }
 
+static int run_vkbd = -1;
+void LockProcess::showVkbd()
+{
+    if( run_vkbd == - 1 ) {
+        int status = system( "hal-find-by-property --key system.formfactor.subtype --string tabletpc" );
+//        status = 0; // enable for testing
+        run_vkbd = ( WIFEXITED( status ) && WEXITSTATUS( status ) == 0
+            && !KStandardDirs::findExe( "xvkbd" ).isEmpty()) ? 1 : 0;
+    }
+    if( run_vkbd ) {
+        mVkbdWindows.clear();
+        mVkbdLastEventWindow = None;
+        mKWinModule = new KWinModule( NULL, KWinModule::INFO_WINDOWS );
+        connect( mKWinModule, TQT_SIGNAL( windowAdded( WId )), TQT_SLOT( windowAdded( WId )));
+        mVkbdProcess = new KProcess;
+        *mVkbdProcess << "xvkbd" << "-compact" << "-geometry" << "-0-0" << "-xdm";
+        mVkbdProcess->start();
+    }
+}
+
+void LockProcess::hideVkbd()
+{
+    if( mVkbdProcess != NULL ) {
+        mVkbdProcess->kill();
+        delete mVkbdProcess;
+        mVkbdProcess = NULL;
+        delete mKWinModule;
+        mKWinModule = NULL;
+        mVkbdWindows.clear();
+    }
+}
+
+void LockProcess::windowAdded( WId w )
+{
+    windowAdded( w, true );
+}
+
+void LockProcess::windowAdded( WId w, bool managed )
+{
+    KWin::WindowInfo info = KWin::windowInfo( w, 0, NET::WM2WindowClass );
+    if( info.windowClassClass().lower() != "xvkbd" )
+        return;
+    // Unmanaged windows (i.e. popups) don't currently work anyway, since they
+    // don't have WM_CLASS set anyway. I could perhaps try tricks with X id
+    // ranges if really needed.
+    if( managed ) {
+        // withdraw the window, wait for it to be withdrawn, reparent it directly
+        // to root at the right position
+        XWithdrawWindow( qt_xdisplay(), w, qt_xscreen());
+        for(;;) {
+            Atom type;
+            int format;
+            unsigned long length, after;
+            unsigned char *data;
+            int r = XGetWindowProperty( qt_xdisplay(), w, qt_wm_state, 0, 2,
+                                        false, AnyPropertyType, &type, &format,
+                                        &length, &after, &data );
+            bool withdrawn = true;
+            if ( r == Success && data && format == 32 ) {
+                Q_UINT32 *wstate = (Q_UINT32*)data;
+                withdrawn  = (*wstate == WithdrawnState );
+                XFree( (char *)data );
+            }
+            if( withdrawn )
+                break;
+        }
+    }
+    XSelectInput( qt_xdisplay(), w, StructureNotifyMask );
+    XWindowAttributes attr_geom;
+    if( !XGetWindowAttributes( qt_xdisplay(), w, &attr_geom ))
+        return;
+    int x = XDisplayWidth( qt_xdisplay(), qt_xscreen()) - attr_geom.width;
+    int y = XDisplayHeight( qt_xdisplay(), qt_xscreen()) - attr_geom.height;
+    if( managed ) {
+        XSetWindowAttributes attr;
+        attr.override_redirect = True;
+        XChangeWindowAttributes( qt_xdisplay(), w, CWOverrideRedirect, &attr );
+        XReparentWindow( qt_xdisplay(), w, qt_xrootwin(), x, y );
+        XMapWindow( qt_xdisplay(), w );
+    }
+    VkbdWindow data;
+    data.id = w;
+    data.rect = TQRect( x, y, attr_geom.width, attr_geom.height );
+    mVkbdWindows.prepend( data );
+}
+
+bool LockProcess::forwardVkbdEvent( XEvent* event )
+{
+    if( mVkbdProcess == NULL )
+        return false;
+    TQPoint pos;
+    Time time;
+    switch( event->type )
+    {
+        case ButtonPress:
+        case ButtonRelease:
+            pos = TQPoint( event->xbutton.x, event->xbutton.y );
+            time = event->xbutton.time;
+            break;
+        case MotionNotify:
+            pos = TQPoint( event->xmotion.x, event->xmotion.y );
+            time = event->xmotion.time;
+            break;
+        default:
+            return false;
+    }
+    // vkbd windows are kept topmost, so just find the first one in the position
+    for( TQValueList< VkbdWindow >::ConstIterator it = mVkbdWindows.begin();
+         it != mVkbdWindows.end();
+         ++it ) {
+        if( (*it).rect.contains( pos )) {
+            // Find the subwindow where the event should actually go.
+            // Not exactly cheap in the number of X roundtrips but oh well.
+            Window window = (*it).id;
+            Window root, child;
+            int root_x, root_y, x, y;
+            unsigned int mask;
+            for(;;) {
+                if( !XQueryPointer( qt_xdisplay(), window, &root, &child, &root_x, &root_y, &x, &y, &mask ))
+                    return false;
+                if( child == None )
+                    break;
+                window = child;
+            }
+            switch( event->type )
+            {
+                case ButtonPress:
+                case ButtonRelease:
+                    event->xbutton.x = x;
+                    event->xbutton.y = y;
+                    event->xbutton.subwindow = None;
+                    break;
+                case MotionNotify:
+                    event->xmotion.x = x;
+                    event->xmotion.y = y;
+                    event->xmotion.subwindow = None;
+                    break;
+            }
+            event->xany.window = window;
+            sendVkbdFocusInOut( window, time );
+            XSendEvent( qt_xdisplay(), window, False, 0, event );
+            return true;
+        }
+    }
+    sendVkbdFocusInOut( None, time );
+    return false;
+}
+
+// Fake EnterNotify/LeaveNotify events as the mouse moves. They're not sent by X
+// because of the grab and having them makes xvkbd highlight the buttons (but
+// not needed otherwise it seems).
+void LockProcess::sendVkbdFocusInOut( WId window, Time t )
+{
+    if( mVkbdLastEventWindow == window )
+        return;
+    if( mVkbdLastEventWindow != None ) {
+        XEvent e;
+        e.xcrossing.type = LeaveNotify;
+        e.xcrossing.display = qt_xdisplay();
+        e.xcrossing.window = mVkbdLastEventWindow;
+        e.xcrossing.root = qt_xrootwin();
+        e.xcrossing.subwindow = None;
+        e.xcrossing.time = t;
+        e.xcrossing.x = 0;
+        e.xcrossing.y = 0;
+        e.xcrossing.x_root = -1;
+        e.xcrossing.y_root = -1;
+        e.xcrossing.mode = NotifyNormal;
+        e.xcrossing.detail = NotifyAncestor;
+        e.xcrossing.same_screen = True;
+        e.xcrossing.focus = False;
+        e.xcrossing.state = 0;
+        XSendEvent( qt_xdisplay(), mVkbdLastEventWindow, False, 0, &e );
+    }
+    mVkbdLastEventWindow = window;
+    if( mVkbdLastEventWindow != None ) {
+        XEvent e;
+        e.xcrossing.type = EnterNotify;
+        e.xcrossing.display = qt_xdisplay();
+        e.xcrossing.window = mVkbdLastEventWindow;
+        e.xcrossing.root = qt_xrootwin();
+        e.xcrossing.subwindow = None;
+        e.xcrossing.time = t;
+        e.xcrossing.x = 0;
+        e.xcrossing.y = 0;
+        e.xcrossing.x_root = 0;
+        e.xcrossing.y_root = 0;
+        e.xcrossing.mode = NotifyNormal;
+        e.xcrossing.detail = NotifyAncestor;
+        e.xcrossing.same_screen = True;
+        e.xcrossing.focus = False;
+        e.xcrossing.state = 0;
+        XSendEvent( qt_xdisplay(), mVkbdLastEventWindow, False, 0, &e );
+    }
+}
+
 #include "lockprocess.moc"
diff --git a/kdesktop/lock/lockprocess.h b/kdesktop/lock/lockprocess.h
index cdbeb0da1..76ffb6013 100644
--- a/kdesktop/lock/lockprocess.h
+++ b/kdesktop/lock/lockprocess.h
@@ -23,6 +23,7 @@
 #include <X11/Xlib.h>
 
 class KLibrary;
+class KWinModule;
 
 struct GreeterPluginHandle {
     KLibrary *library;
@@ -79,6 +80,7 @@ private slots:
     void suspend();
     void checkDPMSActive();
     void slotDeadTimePassed();
+    void windowAdded( WId );
 
 private:
     void configure();
@@ -103,6 +105,11 @@ private:
     void stayOnTop();
     void lockXF86();
     void unlockXF86();
+    void showVkbd();
+    void hideVkbd();
+    bool forwardVkbdEvent( XEvent* event );
+    void sendVkbdFocusInOut( WId window, Time t );
+    void windowAdded( WId window, bool managed );
     void resume( bool force );
     static TQVariant getConf(void *ctx, const char *key, const TQVariant &dflt);
 
@@ -135,18 +142,29 @@ private:
     int         mAutoLogoutTimerId;
     int         mAutoLogoutTimeout;
     bool        mAutoLogout;
-    bool        mInfoMessageDisplayed;
-    TQDialog     *currentDialog;
-    bool        mDialogControlLock;
-    bool        mForceReject;
+
+    TQTimer      *resizeTimer;
+    unsigned int  mkeyCode;
+
+    KProcess*   mVkbdProcess;
+    KWinModule* mKWinModule;
+    struct VkbdWindow
+        {
+        WId id;
+        QRect rect;
+        };
+    QValueList< VkbdWindow > mVkbdWindows;
+    WId         mVkbdLastEventWindow;
 
     bool        mPipeOpen;
     int         mPipe_fd;
     bool        mPipeOpen_out;
     int         mPipe_fd_out;
 
-    TQTimer      *resizeTimer;
-    unsigned int  mkeyCode;
+    bool        mInfoMessageDisplayed;
+    TQDialog     *currentDialog;
+    bool        mDialogControlLock;
+    bool        mForceReject;
 };
 
 #endif
diff --git a/kdesktop/minicli.cpp b/kdesktop/minicli.cpp
index caef6197a..027aa0bfc 100644
--- a/kdesktop/minicli.cpp
+++ b/kdesktop/minicli.cpp
@@ -145,6 +145,9 @@ Minicli::Minicli( TQWidget *parent, const char *name)
   connect( m_dlg->cbCommand, TQT_SIGNAL( returnPressed() ),
            m_dlg->pbRun, TQT_SLOT( animateClick() ) );
 
+  m_dlg->cbCommand->setHistoryEditorEnabled( true );
+  connect( m_dlg->cbCommand, TQT_SIGNAL(removed( const TQString&) ), TQT_SLOT(saveConfig()) );
+
   // Advanced group box...
   connect(m_dlg->cbPriority, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChangeScheduler(bool)));
   connect(m_dlg->slPriority, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(slotPriority(int)));
@@ -295,7 +298,9 @@ void Minicli::accept()
   }
 
   bool logout = (cmd == "logout");
-  if( !logout && runCommand() == 1 )
+  bool lock = (cmd == "lock");
+
+  if( !logout && !lock && runCommand() == 1 )
      return;
 
   m_dlg->cbCommand->addToHistory( m_dlg->cbCommand->currentText().stripWhiteSpace() );
@@ -308,6 +313,14 @@ void Minicli::accept()
      kapp->propagateSessionManager();
      kapp->requestShutDown();
   }
+  if ( lock )
+  {
+     TQCString appname( "kdesktop" );
+     int kicker_screen_number = qt_xscreen();
+     if ( kicker_screen_number )
+         appname.sprintf("kdesktop-screen-%d", kicker_screen_number);
+     kapp->dcopClient()->send(appname, "KScreensaverIface", "lock()", "");
+  }
 }
 
 void Minicli::reject()
diff --git a/kdesktop/minicli.h b/kdesktop/minicli.h
index ddbe868c0..4ae49cf7c 100644
--- a/kdesktop/minicli.h
+++ b/kdesktop/minicli.h
@@ -54,12 +54,14 @@ public:
 
   void setCommand(const TQString& command);
   void reset();
-  void saveConfig();
   void clearHistory();
   
   virtual void show();
   virtual TQSize sizeHint() const;
 
+public slots:
+  void saveConfig();
+
 protected slots:
   virtual void accept();
   virtual void reject();
diff --git a/kdesu/kdesu/kdesu.cpp b/kdesu/kdesu/kdesu.cpp
index af2986b06..67ea55fe9 100644
--- a/kdesu/kdesu/kdesu.cpp
+++ b/kdesu/kdesu/kdesu.cpp
@@ -382,6 +382,7 @@ static int startApp()
             change_uid = false;
         password = dlg.password();
         keep = dlg.keep();
+        KConfigGroup(config,"Passwords").writeEntry("Keep", keep);
         data.setSilent( KStartupInfoData::No );
         KStartupInfo::sendChange( id, data );
     }
diff --git a/kdesu/kdesud/kdesud.cpp b/kdesu/kdesud/kdesud.cpp
index 3e9462698..49006a401 100644
--- a/kdesu/kdesud/kdesud.cpp
+++ b/kdesu/kdesud/kdesud.cpp
@@ -45,6 +45,7 @@
 #include <pwd.h>
 #include <errno.h>
 
+#include <sys/prctl.h>
 #include <sys/time.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -248,6 +249,8 @@ int create_socket()
 
 int main(int argc, char *argv[])
 {
+    prctl(PR_SET_DUMPABLE, 0);
+
     KAboutData aboutData("kdesud", I18N_NOOP("KDE su daemon"),
             Version, I18N_NOOP("Daemon used by kdesu"),
             KAboutData::License_Artistic,
diff --git a/kdm/backend/client.c b/kdm/backend/client.c
index b2e7ebbc7..0807b2ce7 100644
--- a/kdm/backend/client.c
+++ b/kdm/backend/client.c
@@ -87,6 +87,18 @@ extern int loginsuccess( const char *User, const char *Host, const char *Tty, ch
 #include "consolekit.h"
 #endif
 
+#define  AU_FAILED 0
+#define  AU_SUCCESS 1
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+#else
+#define log_to_audit_system(l,h,d,s)	do { ; } while (0)
+#endif
+
+#ifdef WITH_CONSOLE_KIT
+#include "consolekit.h"
+#endif
+
 /*
  * Session data, mostly what struct verify_info was for
  */
@@ -291,6 +303,56 @@ fail_delay( int retval ATTR_UNUSED, unsigned usec_delay ATTR_UNUSED,
 {}
 # endif
 
+ /**
+ * log_to_audit_system:
+ * @login: Name of user
+ * @hostname: Name of host machine
+ * @tty: Name of display 
+ * @success: 1 for success, 0 for failure
+ *
+ * Logs the success or failure of the login attempt with the linux kernel
+ * audit system. The intent is to capture failed events where the user
+ * fails authentication or otherwise is not permitted to login. There are
+ * many other places where pam could potentially fail and cause login to 
+ * fail, but these are system failures rather than the signs of an account
+ * being hacked.
+ *
+ * Returns nothing.
+ */
+
+#ifdef HAVE_LIBAUDIT
+static void 
+log_to_audit_system (const char *loginname,
+		     const char *hostname,
+		     const char *tty,
+		     int success)
+{
+	struct passwd *pw;
+	char buf[64];
+	int audit_fd;
+
+	audit_fd = audit_open();
+	if (loginname)
+		pw = getpwnam(loginname);
+	else {
+		loginname = "unknown";
+		pw = NULL;
+	}
+	Debug("log_to_audit %p %s\n", pw, loginname);
+
+	if (pw) {
+		snprintf(buf, sizeof(buf), "uid=%d", pw->pw_uid);
+		audit_log_user_message(audit_fd, AUDIT_USER_LOGIN,
+			buf, hostname, NULL, tty, (int)success);
+	} else {
+		snprintf(buf, sizeof(buf), "acct=%s", loginname);
+		audit_log_user_message(audit_fd, AUDIT_USER_LOGIN,
+			buf, hostname, NULL, tty, (int)success);
+	}
+	close(audit_fd);
+}
+#endif
+
 static int
 doPAMAuth( const char *psrv, struct pam_data *pdata )
 {
@@ -349,6 +411,8 @@ doPAMAuth( const char *psrv, struct pam_data *pdata )
 		GSendStr( curuser );
 	}
 	if (pretc != PAM_SUCCESS) {
+	        /* Log the failed login attempt */
+	        log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
 		switch (pretc) {
 		case PAM_USER_UNKNOWN:
 		case PAM_AUTH_ERR:
@@ -484,6 +548,9 @@ Verify( GConvFunc gconv, int rootok )
 		} else
 			psrv = PAMService;
 		pdata.usecur = TRUE;
+        } else if (!strcmp( curtype, "pam" )) {
+		psrv = PAMService;
+		pdata.usecur = FALSE;
 	} else {
 		sprintf( psrvb, "%.31s-%.31s", PAMService, curtype );
 		psrv = psrvb;
@@ -553,7 +620,7 @@ Verify( GConvFunc gconv, int rootok )
 			free( msg );
 			V_RET_FAIL( 0 );
 		}
-	} else if (!strcmp( curtype, "generic" )) {
+	} else if (!strcmp( curtype, "generic" ) || !strcmp(curtype, "pam")) {
 		if (!gconv( GCONV_USER, 0 ))
 			return 0;
 		for (curret = 0;;) {
@@ -699,6 +766,8 @@ Verify( GConvFunc gconv, int rootok )
 	if (!p->pw_uid) {
 		if (!rootok && !td->allowRootLogin)
 			V_RET_FAIL( "Root logins are not allowed" );
+		/* Log the failed login attempt */
+		log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
 		return 1; /* don't deny root to log in */
 	}
 
@@ -735,6 +804,8 @@ Verify( GConvFunc gconv, int rootok )
 			}
 			if (pretc == PAM_SUCCESS)
 				break;
+			/* Log the failed login attempt */
+			log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
 			/* effectively there is only PAM_AUTHTOK_ERR */
 			GSendInt( V_FAIL );
 		}
@@ -824,6 +895,8 @@ Verify( GConvFunc gconv, int rootok )
 				GSendInt( V_MSG_ERR );
 				GSendStr( "Your account has expired;"
 				          " please contact your system administrator" );
+				/* Log the failed login attempt */
+				log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
 				GSendInt( V_FAIL );
 				LC_RET0;
 			} else if (tim > (expir - warntime) && !quietlog) {
@@ -858,6 +931,8 @@ Verify( GConvFunc gconv, int rootok )
 				GSendInt( V_MSG_ERR );
 				GSendStr( "Your account has expired;"
 				          " please contact your system administrator" );
+				/* Log the failed login attempt */
+				log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
 				GSendInt( V_FAIL );
 				LC_RET0;
 			}
@@ -917,6 +992,8 @@ Verify( GConvFunc gconv, int rootok )
 			close( fd );
 		}
 		GSendStr( "Logins are not allowed at the moment.\nTry again later" );
+		/* Log the failed login attempt */
+		log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
 		GSendInt( V_FAIL );
 		LC_RET0;
 	}
@@ -927,6 +1004,8 @@ Verify( GConvFunc gconv, int rootok )
 		PrepErrorGreet();
 		GSendInt( V_MSG_ERR );
 		GSendStr( "You are not allowed to login at the moment" );
+		/* Log the failed login attempt */
+		log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
 		GSendInt( V_FAIL );
 		LC_RET0;
 	}
@@ -938,6 +1017,8 @@ Verify( GConvFunc gconv, int rootok )
 			Debug( "shell not in /etc/shells\n" );
 			endusershell();
 			V_RET_FAIL( "Your login shell is not listed in /etc/shells" );
+			/* Log the failed login attempt */
+			log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
 		}
 		if (!strcmp( s, p->pw_shell )) {
 			endusershell();
@@ -1223,10 +1304,17 @@ StartClient()
 	env = setEnv( env, "PATH", curuid ? td->userPath : td->systemPath );
 	env = setEnv( env, "SHELL", p->pw_shell );
 	env = setEnv( env, "HOME", p->pw_dir );
+	if (cursource == PWSRC_AUTOLOGIN)
+		env = setEnv (env, "KDM_AUTOLOGIN", curuser);
 #if !defined(USE_PAM) && !defined(_AIX) && defined(KERBEROS)
 	if (krbtkfile[0] != '\0')
 		env = setEnv( env, "KRBTKFILE", krbtkfile );
 #endif
+#ifdef WITH_CONSOLE_KIT
+	if (ck_session_cookie != NULL) {
+		env = setEnv ( env, "XDG_SESSION_COOKIE", ck_session_cookie );
+	}
+#endif
 #ifdef WITH_CONSOLE_KIT
 	if (ck_session_cookie != NULL) {
 		env = setEnv ( env, "XDG_SESSION_COOKIE", ck_session_cookie );
@@ -1360,6 +1448,9 @@ StartClient()
 # define D_LOGIN_SETGROUP 0
 #endif /* USE_PAM */
 
+	/* Login succeeded */
+	log_to_audit_system (curuser, td->remoteHost, td->name, AU_SUCCESS);
+
 	removeAuth = 1;
 	chownCtrl( &td->ctrl, curuid );
 	endpwent();
diff --git a/kdm/config.def b/kdm/config.def
index ab1adac84..7bc39b36d 100644
--- a/kdm/config.def
+++ b/kdm/config.def
@@ -1985,6 +1985,17 @@ Description:
  Specify the widget style for the greeter. Empty means to use the
  built-in default which currently is <literal>Plastik</literal>.
 
+Key: UseAdminSession
+Type: bool
+Default: false
+User: greeter
+Instance: #*/!
+Comment:
+ Admin session
+Description:
+ If given there will be a special button that requires root password
+ and starts the given session
+
 Key: ColorScheme
 Type: string
 Default: ""
diff --git a/kdm/configure.in.in b/kdm/configure.in.in
index 4b6972178..da741e7f9 100644
--- a/kdm/configure.in.in
+++ b/kdm/configure.in.in
@@ -240,6 +240,53 @@ if test "x$with_kdm_xconsole" = xyes; then
     AC_DEFINE(WITH_KDM_XCONSOLE, 1, [Build kdm with built-in xconsole])
 fi
 
+########### Check for DBus
+
+  AC_MSG_CHECKING(for DBus)
+
+  dbus_inc=NOTFOUND
+  dbus_lib=NOTFOUND
+  dbus=NOTFOUND
+
+  search_incs="$kde_includes $kde_extra_includes /usr/include /usr/include/dbus-1.0 /usr/local/include /usr/local/include/dbus-1.0"
+  AC_FIND_FILE(dbus/dbus.h, $search_incs, dbus_incdir)
+
+  search_incs_arch_deps="$kde_includes $kde_extra_includes /usr/lib$kdelibsuff/dbus-1.0/include /usr/local/lib$kdelibsuff/dbus-1.0/include"
+  AC_FIND_FILE(dbus/dbus-arch-deps.h, $search_incs_arch_deps, dbus_incdir_arch_deps)
+
+  if test -r $dbus_incdir/dbus/dbus.h && test -r $dbus_incdir_arch_deps/dbus/dbus-arch-deps.h ; then
+    DBUS_INCS="-I$dbus_incdir -I$dbus_incdir_arch_deps"
+    dbus_inc=FOUND
+  fi
+
+  search_libs="$kde_libraries $kde_extra_libs /usr/lib$kdelibsuff /usr/local/lib$kdelibsuff"
+  AC_FIND_FILE(libdbus-1.so, $search_libs, dbus_libdir)
+
+  if test -r $dbus_libdir/libdbus-1.so ; then
+    DBUS_LIBS="-L$dbus_libdir -ldbus-1"
+    dbus_lib=FOUND
+  fi
+
+  if test $dbus_inc != FOUND || test $dbus_lib != FOUND ; then 
+    KDE_PKG_CHECK_MODULES( DBUS, "dbus-1", [ DBUS_INCS=$DBUS_CFLAGS; dbus_inc=FOUND; dbus_lib=FOUND; ] , AC_MSG_RESULT( Nothing found on PKG_CONFIG_PATH ) )
+  fi
+
+  dbus_bus_var=`pkg-config --variable=system_bus_default_address dbus-1 2>/dev/null`
+  if test -z "$dbus_bus_var"; then
+        dbus_bus_var="unix:path=/var/run/dbus/system_bus_socket"
+  fi
+  AC_DEFINE_UNQUOTED(DBUS_SYSTEM_BUS, "$dbus_bus_var", [Define the unix domain path for dbus system bus])
+
+  if test $dbus_inc = FOUND && test $dbus_lib = FOUND ; then
+    AC_MSG_RESULT(headers $DBUS_INCS libraries $DBUS_LIBS)
+    dbus=FOUND
+  else
+    AC_MSG_RESULT(searched but not found)
+  fi
+
+  AC_SUBST(DBUS_INCS)
+  AC_SUBST(DBUS_LIBS)
+
 ########### Check for DBus
 
   AC_MSG_CHECKING(for DBus)
@@ -288,3 +335,27 @@ fi
   AC_SUBST(DBUS_LIBS)
 
 dnl AC_OUTPUT(kdm/kfrontend/sessions/kde.desktop)
+
+
+AC_ARG_WITH(libaudit,
+  [  --with-libaudit=[auto/yes/no]  Add Linux audit support [default=auto]],,
+  with_libaudit=auto)
+
+# Check for Linux auditing API
+#
+# libaudit detection
+if test x$with_libaudit = xno ; then
+    have_libaudit=no;
+else
+    # See if we have audit daemon library
+    AC_CHECK_LIB(audit, audit_log_user_message,
+                 have_libaudit=yes, have_libaudit=no)
+fi
+
+AM_CONDITIONAL(HAVE_LIBAUDIT, test x$have_libaudit = xyes)
+
+if test x$have_libaudit = xyes ; then
+    EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -laudit"
+    AC_DEFINE(HAVE_LIBAUDIT,1,[linux audit support])
+fi
+
diff --git a/kdm/kfrontend/Makefile.am b/kdm/kfrontend/Makefile.am
index 5c5dfd61a..6d4fed27b 100644
--- a/kdm/kfrontend/Makefile.am
+++ b/kdm/kfrontend/Makefile.am
@@ -21,6 +21,7 @@ kdm_greet_SOURCES = \
     kchooser.cpp \
     kgverify.cpp \
     kdmshutdown.cpp \
+    kdmadmindialog.cpp \
     kgreeter.cpp \
     kgapp.cpp
 kdm_greet_LDFLAGS = $(all_libraries) $(KDE_RPATH)
diff --git a/kdm/kfrontend/kdm_greet.c b/kdm/kfrontend/kdm_greet.c
index 53d164f45..b03d96e15 100644
--- a/kdm/kfrontend/kdm_greet.c
+++ b/kdm/kfrontend/kdm_greet.c
@@ -44,8 +44,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 # include <sched.h>
 #endif
 
-#if defined(HAVE_XTEST) || defined(HAVE_XKB)
 # include <X11/Xlib.h>
+#if defined(HAVE_XTEST) || defined(HAVE_XKB)
 # include <X11/keysym.h>
 #endif
 
diff --git a/kdm/kfrontend/kdmadmindialog.cpp b/kdm/kfrontend/kdmadmindialog.cpp
new file mode 100644
index 000000000..637d6dd90
--- /dev/null
+++ b/kdm/kfrontend/kdmadmindialog.cpp
@@ -0,0 +1,176 @@
+    /*
+
+    Admin dialog
+
+    Copyright (C) 1997, 1998, 2000 Steffen Hansen <hansen@kde.org>
+    Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org>
+
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+    */
+
+#include "kdmadmindialog.h"
+#include "kdmconfig.h"
+#include "kgdialog.h"
+#include "kdm_greet.h"
+#include <stdlib.h>
+
+#include <kapplication.h>
+#include <kseparator.h>
+#include <klocale.h>
+#include <kpushbutton.h>
+#include <kstdguiitem.h>
+
+#include <tqcombobox.h>
+#include <tqvbuttongroup.h>
+#include <tqstyle.h>
+#include <tqlayout.h>
+#include <tqaccel.h>
+#include <tqpopupmenu.h>
+
+int KDMAdmin::curPlugin = -1;
+PluginList KDMAdmin::pluginList;
+
+KDMAdmin::KDMAdmin( const TQString &user, TQWidget *_parent )
+    : inherited( _parent )
+    , verify( 0 ), curUser(user)
+{
+    TQSizePolicy fp( TQSizePolicy::Fixed, TQSizePolicy::Fixed );
+
+    TQVBoxLayout *box = new TQVBoxLayout( this, 10 );
+
+    TQHBoxLayout *hlay = new TQHBoxLayout( box );
+
+    GSendInt( G_ReadDmrc );
+    GSendStr( "root" );
+    GRecvInt(); // ignore status code ...
+
+    if (curPlugin < 0) {
+       curPlugin = 0;
+       pluginList = KGVerify::init( "classic" );
+    }
+    verify = new KGStdVerify( this, this,
+			      this, "root",
+			      pluginList, KGreeterPlugin::Authenticate,
+			      KGreeterPlugin::Shutdown );
+    verify->selectPlugin( curPlugin );
+    box->addLayout( verify->getLayout() );
+    TQAccel *accel = new TQAccel( this );
+    accel->insertItem( ALT+Key_A, 0 );
+    connect( accel, TQT_SIGNAL(activated(int)), TQT_SLOT(slotActivatePlugMenu()) );
+
+    box->addWidget( new KSeparator( KSeparator::HLine, this ) );
+
+    okButton = new KPushButton( KStdGuiItem::ok(), this );
+    okButton->setSizePolicy( fp );
+    okButton->setDefault( true );
+    cancelButton = new KPushButton( KStdGuiItem::cancel(), this );
+    cancelButton->setSizePolicy( fp );
+
+    hlay = new TQHBoxLayout( box );
+    hlay->addStretch( 1 );
+    hlay->addWidget( okButton );
+    hlay->addStretch( 1 );
+    hlay->addWidget( cancelButton );
+    hlay->addStretch( 1 );
+
+    connect( okButton, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) );
+    connect( cancelButton, TQT_SIGNAL(clicked()), TQT_SLOT(reject()) );
+
+    slotWhenChanged();
+}
+
+KDMAdmin::~KDMAdmin()
+{
+    hide();
+    delete verify;
+}
+
+void
+KDMAdmin::slotActivatePlugMenu()
+{
+    TQPopupMenu *cmnu = verify->getPlugMenu();
+    TQSize sh( cmnu->sizeHint() / 2 );
+    cmnu->exec( geometry().center() - TQPoint( sh.width(), sh.height() ) );
+}
+
+void
+KDMAdmin::accept()
+{
+    verify->accept();
+}
+
+void
+KDMAdmin::slotWhenChanged()
+{
+    verify->abort();
+    verify->setEnabled( 1 );
+    verify->start();
+}
+
+void
+KDMAdmin::bye_bye()
+{
+  GSendInt( G_GetDmrc );
+  GSendStr( "Session" );
+  char *sess = GRecvStr();
+  if (sess && strcmp(sess, "admin")) {
+    GSendInt( G_PutDmrc );
+    GSendStr( "OrigSession");
+    GSendStr( sess);
+    free(sess);
+  }
+
+  GSendInt( G_PutDmrc );
+  GSendStr( "Session" );
+  GSendStr( "admin" );
+  inherited::accept();
+}
+
+void
+KDMAdmin::verifyPluginChanged( int id )
+{
+    curPlugin = id;
+    adjustSize();
+}
+
+void
+KDMAdmin::verifyOk()
+{
+    bye_bye();
+}
+
+void
+KDMAdmin::verifyFailed()
+{
+    okButton->setEnabled( false );
+    cancelButton->setEnabled( false );
+}
+
+void
+KDMAdmin::verifyRetry()
+{
+    okButton->setEnabled( true );
+    cancelButton->setEnabled( true );
+}
+
+void
+KDMAdmin::verifySetUser( const TQString & )
+{
+}
+
+
+#include "kdmadmindialog.moc"
diff --git a/kdm/kfrontend/kdmadmindialog.h b/kdm/kfrontend/kdmadmindialog.h
new file mode 100644
index 000000000..91f1ed3a6
--- /dev/null
+++ b/kdm/kfrontend/kdmadmindialog.h
@@ -0,0 +1,70 @@
+    /*
+
+    Shutdown dialog
+
+    Copyright (C) 1997, 1998 Steffen Hansen <hansen@kde.org>
+    Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org>
+
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+    */
+
+
+#ifndef KDMADMIN_H
+#define KDMADMIN_H
+
+#include "kgverify.h"
+
+#include <tqradiobutton.h>
+
+class LiloInfo;
+class TQLabel;
+class KPushButton;
+class TQButtonGroup;
+class TQComboBox;
+
+class KDMAdmin : public FDialog, public KGVerifyHandler {
+    Q_OBJECT
+    typedef FDialog inherited;
+
+public:
+    KDMAdmin( const TQString &user, TQWidget *_parent = 0 );
+    ~KDMAdmin();
+
+public slots:
+    void accept();
+    void slotWhenChanged();
+    void slotActivatePlugMenu();
+
+private:
+    void bye_bye();
+    
+    KPushButton		*okButton, *cancelButton;
+    KGStdVerify		*verify;
+    TQString             curUser;
+
+    static int		curPlugin;
+    static PluginList	pluginList;
+
+public: // from KGVerifyHandler
+    virtual void verifyPluginChanged( int id );
+    virtual void verifyOk();
+    virtual void verifyFailed();
+    virtual void verifyRetry();
+    virtual void verifySetUser( const TQString &user );
+};
+
+#endif
diff --git a/kdm/kfrontend/kdmconfig.cpp b/kdm/kfrontend/kdmconfig.cpp
index 6f4c14031..15a63fa67 100644
--- a/kdm/kfrontend/kdmconfig.cpp
+++ b/kdm/kfrontend/kdmconfig.cpp
@@ -33,6 +33,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #include <unistd.h>
 #include <sys/utsname.h>
 
+struct timeval st = {0, 0};
+
 CONF_GREET_DEFS
 
 TQString _stsFile;
diff --git a/kdm/kfrontend/kdmconfig.h b/kdm/kfrontend/kdmconfig.h
index f5420bcc4..52e054af6 100644
--- a/kdm/kfrontend/kdmconfig.h
+++ b/kdm/kfrontend/kdmconfig.h
@@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #include <tqstring.h>
 #include <tqstringlist.h>
 #include <tqfont.h>
+#include <sys/time.h>
 
 extern TQString _stsFile;
 extern bool _isLocal;
@@ -46,6 +47,19 @@ CONF_GREET_CPP_DECLS
 struct dpySpec;
 void decodeSess( dpySpec *sess, TQString &user, TQString &loc );
 
+extern struct timeval st;
+
+inline TQString timestamp() {
+	struct timeval nst;
+	gettimeofday(&nst, 0);
+	if (!st.tv_sec)
+		gettimeofday(&st, 0);
+
+	TQString ret;
+	ret.sprintf("[%07ld]", (nst.tv_sec - st.tv_sec) * 1000 + (nst.tv_usec - st.tv_usec) / 1000);
+	return ret;
+}
+
 extern "C"
 #endif
 void init_config( void );
diff --git a/kdm/kfrontend/kfdialog.cpp b/kdm/kfrontend/kfdialog.cpp
index 62a4acb22..78359e237 100644
--- a/kdm/kfrontend/kfdialog.cpp
+++ b/kdm/kfrontend/kfdialog.cpp
@@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #include <klocale.h>
 #include <kpushbutton.h>
 #include <kstdguiitem.h>
+#include <kglobalsettings.h>
 
 #include <tqlabel.h>
 #include <tqlayout.h>
@@ -137,6 +138,9 @@ KFMsgBox::KFMsgBox( TQWidget *parent, TQMessageBox::Icon type, const TQString &t
 	TQLabel *label1 = new TQLabel( this );
 	label1->setPixmap( TQMessageBox::standardIcon( type ) );
 	TQLabel *label2 = new TQLabel( text, this );
+	TQRect d = KGlobalSettings::desktopGeometry(this);
+	if ( label2->fontMetrics().size( 0, text).width() > d.width() * 3 / 5) 
+		label2->setAlignment(Qt::WordBreak | Qt::AlignAuto );
 	KPushButton *button = new KPushButton( KStdGuiItem::ok(), this );
 	button->setDefault( true );
 	button->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred ) );
diff --git a/kdm/kfrontend/kgapp.cpp b/kdm/kfrontend/kgapp.cpp
index 70b510645..50e65e916 100644
--- a/kdm/kfrontend/kgapp.cpp
+++ b/kdm/kfrontend/kgapp.cpp
@@ -36,6 +36,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #include <kcrash.h>
 #include <kstandarddirs.h>
 #include <ksimpleconfig.h>
+#include <klocale.h>
+#include <kdebug.h>
 
 #include <tqtimer.h>
 #include <tqstring.h>
@@ -133,6 +135,7 @@ kg_main( const char *argv0 )
 	static char *argv[] = { (char *)"kdmgreet", 0 };
 	KCmdLineArgs::init( 1, argv, *argv, 0, 0, 0, true );
 
+	kdDebug() << timestamp() << "start" << endl;
 	kde_have_kipc = false;
 	KApplication::disableAutoDcopRegistration();
 	KCrash::setSafer( true );
@@ -180,6 +183,7 @@ kg_main( const char *argv0 )
 
 	GSendInt( G_Ready );
 
+	kdDebug() << timestamp() << " main1" << endl;	
 	setCursor( dpy, app.desktop()->winId(), XC_left_ptr );
 
 	for (;;) {
@@ -220,6 +224,7 @@ kg_main( const char *argv0 )
 			if (_useTheme && !_theme.isEmpty()) {
 				KThemedGreeter *tgrt;
 				dialog = tgrt = new KThemedGreeter;
+				kdDebug() << timestamp() << " themed" << endl;	
 				if (!tgrt->isOK()) {
 					delete tgrt;
 					dialog = new KStdGreeter;
diff --git a/kdm/kfrontend/kgdialog.cpp b/kdm/kfrontend/kgdialog.cpp
index 1981eea83..f4ed918c6 100644
--- a/kdm/kfrontend/kgdialog.cpp
+++ b/kdm/kfrontend/kgdialog.cpp
@@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #include "kdm_greet.h"
 
 #include <klocale.h>
+#include <kiconloader.h>
 
 #include <tqaccel.h>
 #include <tqlayout.h>
@@ -84,7 +85,8 @@ KGDialog::completeMenu()
 		inserten( i18n("Co&nsole Login"), ALT+Key_N, TQT_SLOT(slotConsole()) );
 
 	if (_allowShutdown != SHUT_NONE) {
-		inserten( i18n("&Shutdown..."), ALT+Key_S, TQT_SLOT(slotShutdown( int )) );
+                ensureMenu();
+                optMenu->insertItem(SmallIconSet( "exit" ), i18n("&Shutdown..."), this, TQT_SLOT(slotShutdown(int)), ALT+Key_S );
 		TQAccel *accel = new TQAccel( this );
 		accel->insertItem( ALT+CTRL+Key_Delete );
 		connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotShutdown( int )) );
diff --git a/kdm/kfrontend/kgreeter.cpp b/kdm/kfrontend/kgreeter.cpp
index ebd303525..74fc6b090 100644
--- a/kdm/kfrontend/kgreeter.cpp
+++ b/kdm/kfrontend/kgreeter.cpp
@@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #include "kdmconfig.h"
 #include "kdmclock.h"
 #include "kdm_greet.h"
+#include "kdmadmindialog.h"
 #include "themer/kdmthemer.h"
 #include "themer/kdmitem.h"
 #include "themer/kdmlabel.h"
@@ -38,6 +39,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #include <klistview.h>
 #include <ksimpleconfig.h>
 #include <kstringhandler.h>
+#include <kdebug.h>
 
 #undef Unsorted // x headers suck - make tqdir.h work with --enable-final
 #include <tqdir.h>
@@ -46,6 +48,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #include <tqmemarray.h>
 #include <tqimage.h>
 #include <tqmovie.h>
+#include <tqpainter.h>
 #include <tqpopupmenu.h>
 #include <tqtimer.h>
 #include <tqheader.h>
@@ -57,6 +60,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #include <tqaccel.h>
 #include <tqstring.h>
 #include <tqeventloop.h>
+#include <tqbitmap.h>
 
 #include <pwd.h>
 #include <grp.h>
@@ -64,27 +68,46 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/types.h>
+#include <utmp.h>
+#include <utmpx.h>
 
 #include <X11/Xlib.h>
 
 class UserListView : public KListView {
   public:
-	UserListView( TQWidget *parent = 0, const char *name = 0 )
+        UserListView( bool _them, TQWidget *parent = 0, const char *name = 0 )
 		: KListView( parent, name )
-		, cachedSizeHint( -1, 0 )
+		, themed(_them), cachedSizeHint( -1, 0 )
 	{
 		setSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Ignored );
 		header()->hide();
 		addColumn( TQString::null );
 		setColumnAlignment( 0, AlignVCenter );
 		setResizeMode( TQListView::LastColumn );
+		if (themed) {
+		  setBackgroundMode( Qt::NoBackground );
+		  viewport()->setBackgroundMode( Qt::NoBackground );
+		  setFrameStyle( TQFrame::NoFrame );
+		}
 	}
 
+        bool themed;
 	mutable TQSize cachedSizeHint;
 
-  protected:
+        int sumHeight() const 
+  {
+        int sum = 0;
+        for (TQListViewItem *itm = firstChild(); itm; itm = itm->nextSibling()) {
+            sum += itm->height();
+        }
+        return sum;
+    }
+public:
 	virtual TQSize sizeHint() const
 	{
+	  if (themed)
+            return KListView::sizeHint();
+
 		if (!cachedSizeHint.isValid()) {
 			constPolish();
 			uint maxw = 0;
@@ -99,9 +122,24 @@ class UserListView : public KListView {
 		}
 		return cachedSizeHint;
 	}
+    virtual void paintEmptyArea ( TQPainter * p, const TQRect & rect )
+    {
+      if (!themed)
+        return KListView::paintEmptyArea(p, rect );
+
+        const TQPixmap *pm = paletteBackgroundPixmap();
+        if (!pm || pm->isNull())
+            return;
+
+        kdDebug() << "paintEmpty " << rect << endl;
+        TQRect devRect = p->xForm( rect );
+        kdDebug() << "paintEmpty2 " << devRect << endl;
+        p->drawPixmap(0, 0, *pm, devRect.left(), devRect.top() );
+    }
+
+    TQPixmap background;
 };
 
-
 int KGreeter::curPlugin = -1;
 PluginList KGreeter::pluginList;
 
@@ -116,12 +154,14 @@ KGreeter::KGreeter( bool framed )
   , curSel( -1 )
   , prevValid( true )
   , needLoad( false )
+  , themed( framed )
 {
 	stsFile = new KSimpleConfig( _stsFile );
 	stsFile->setGroup( "PrevUser" );
 
 	if (_userList) {
-		userView = new UserListView( this );
+                readFacesList();
+		userView = new UserListView( framed, this );
 		connect( userView, TQT_SIGNAL(clicked( TQListViewItem * )),
 		         TQT_SLOT(slotUserClicked( TQListViewItem * )) );
 		connect( userView, TQT_SIGNAL(doubleClicked( TQListViewItem * )),
@@ -129,10 +169,8 @@ KGreeter::KGreeter( bool framed )
 	}
 	if (_userCompletion)
 		userList = new TQStringList;
-	if (userView || userList)
-		insertUsers();
 
-	sessMenu = new TQPopupMenu( this );
+        sessMenu = new TQPopupMenu( this );
 	connect( sessMenu, TQT_SIGNAL(activated( int )),
 	         TQT_SLOT(slotSessionSelected( int )) );
 	insertSessions();
@@ -151,6 +189,33 @@ KGreeter::~KGreeter()
 	delete stsFile;
 }
 
+void KGreeter::readFacesList()
+{
+    FILE *f = fopen( TQFile::encodeName( _faceDir + "/.randomlist" ), "rt" );
+    if ( !f )
+        return;
+    TQTextIStream is( f );
+    while ( !is.eof() )
+    {
+        TQString line = is.readLine().simplifyWhiteSpace();
+        if ( line.isEmpty() )
+            continue;
+        TQString icon;
+        int index = line.find( ' ' );
+        if ( index > 0 ) {
+            icon = line.left( index );
+            line = line.mid( index );
+        } else {
+            icon = line;
+            line = TQString::null;
+        }
+        randomFaces.push_back( icon );
+        TQStringList list = TQStringList::split( ' ', line );
+        for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
+            randomFacesMap[*it] = icon;
+    }
+}
+
 class UserListViewItem : public KListViewItem {
   public:
 	UserListViewItem( UserListView *parent, const TQString &text,
@@ -164,6 +229,14 @@ class UserListViewItem : public KListViewItem {
 		parent->cachedSizeHint.setWidth( -1 );
 	}
 
+        virtual void paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int alignment)
+    {
+      if (((UserListView*)listView())->themed)
+        TQListViewItem::paintCell(p, cg, column, width, alignment);
+      else
+	KListViewItem::paintCell(p, cg, column, width, alignment);
+    }
+
 	TQString login;
 };
 
@@ -232,10 +305,23 @@ KGreeter::insertUser( const TQImage &default_pix,
 		TQSize ns( 48, 48 );
 		if (p.size() != ns)
 			p = p.convertDepth( 32 ).smoothScale( ns, TQImage::ScaleMin );
-		goto gotit;
+		break;
 	} while (--nd >= 0);
-	p = default_pix;
-  gotit:
+
+        if ( p.isNull() && randomFaces.count() ) {
+            TQString randomFace = randomFacesMap[username];
+            if ( randomFace.isNull() ) {
+                TQStringList::size_type index = 0;
+                for ( size_t i = 0; i < username.length(); ++i )
+                    index += ( 0x7f - username.at( i ).latin1() ) % 37;
+                randomFace = randomFaces[ index % randomFaces.count() ];
+            }
+            p.load( _faceDir + "/../pics/users/" + randomFace + ".png" );
+        }
+
+        if ( p.isNull() )
+            p = default_pix;
+
 	TQString realname = KStringHandler::from8Bit( ps->pw_gecos );
 	realname.truncate( realname.find( ',' ) );
 	if (realname.isEmpty() || realname == username)
@@ -289,7 +375,7 @@ UserList::UserList( char **in )
 }
 
 void
-KGreeter::insertUsers()
+KGreeter::insertUsers(int limit_users)
 {
 	struct passwd *ps;
 
@@ -309,6 +395,8 @@ KGreeter::insertUsers()
 	if (_showUsers == SHOW_ALL) {
 		UserList noUsers( _noUsers );
 		TQDict<int> dupes( 1000 );
+                TQStringList toinsert;
+                int count = 0;
 		for (setpwent(); (ps = getpwent()) != 0;) {
 			if (*ps->pw_dir && *ps->pw_shell &&
 			    (ps->pw_uid >= (unsigned)_lowUserId ||
@@ -320,10 +408,53 @@ KGreeter::insertUsers()
 				TQString username( TQFile::decodeName( ps->pw_name ) );
 				if (!dupes.find( username )) {
 					dupes.insert( username, (int *)-1 );
-					insertUser( default_pix, username, ps );
+                                        toinsert.append( username );
+
+                                        if ( limit_users >= 0 && ++count > limit_users )
+                                            break;
 				}
 			}
 		}
+                if ( limit_users >= 0 && ++count > limit_users ) {
+                    utmpname( _PATH_WTMP );
+                    setutxent();
+                    toinsert = TQStringList();
+                    dupes.clear();
+
+                    for ( count = 0; count < limit_users; ) {
+                        struct utmpx * ent = getutxent();
+                        if ( !ent )
+                            break;
+                        struct passwd *ps = getpwnam( ent->ut_user );
+                        if (ps && *ps->pw_dir && *ps->pw_shell &&
+			    (ps->pw_uid >= (unsigned)_lowUserId ||
+			     !ps->pw_uid && _showRoot) &&
+			    ps->pw_uid <= (unsigned)_highUserId &&
+			    !noUsers.hasUser( ps->pw_name ) &&
+			    !noUsers.hasGroup( ps->pw_gid ))
+                        {
+                            TQString username( TQFile::decodeName( ent->ut_user ) );
+                            if (!dupes.find( username )) {
+                                dupes.insert( username, (int *)-1 );
+                                toinsert.append( username );
+                                count++;
+                            }
+                        }
+
+
+                    }
+                    endutxent();
+                }
+
+                for ( TQStringList::ConstIterator it = toinsert.begin();
+                      it != toinsert.end(); ++it )
+                {
+                    // pretty stupid to do another lookup round, but the number is limited
+                    // and caching struct passwd is pretty ugly
+                    struct passwd *ps = getpwnam( TQFile::encodeName( *it ) );
+                    if ( ps )
+                        insertUser( default_pix, *it, ps );
+                }
 	} else {
 		UserList users( _users );
 		if (users.hasGroups()) {
@@ -379,7 +510,7 @@ KGreeter::insertSessions()
 	for (char **dit = _sessionsDirs; *dit; ++dit) {
 		TQStringList ents = TQDir( *dit ).entryList();
 		for (TQStringList::ConstIterator it = ents.begin(); it != ents.end(); ++it)
-			if ((*it).endsWith( ".desktop" )) {
+		  if ((*it).endsWith( ".desktop" ) && !(*it).endsWith("admin.desktop")) {
 				KSimpleConfig dsk( TQString( *dit ).append( '/' ).append( *it ) );
 				dsk.setGroup( "Desktop Entry" );
 				putSession( (*it).left( (*it).length() - 8 ),
@@ -517,6 +648,17 @@ KGreeter::slotLoadPrevWM()
 				return;
 			}
 		} else {
+		  if (!strcmp(sess, "admin")) {
+		    // need to get the original
+		    GSendInt( G_GetDmrc);
+		    GSendStr( "OrigSession");
+		    sess = GRecvStr();
+		    if (!sess) {
+		      free(sess);
+		      sess = strdup("default");
+		    }
+		  }
+
 			for (uint i = 0; i < sessionTypes.count() && !sessionTypes[i].hid; i++)
 				if (sessionTypes[i].type == sess) {
 					free( sess );
@@ -718,21 +860,24 @@ KStdGreeter::KStdGreeter()
 	hbox2->addStretch( 1 );
 
 	if (sessMenu->count() > 1) {
-		inserten( i18n("Session &Type"), ALT+Key_T, sessMenu );
+		inserten( i18n("Session &Type"), 0, sessMenu );
 		needSep = true;
 	}
 
 	if (plugMenu) {
-		inserten( i18n("&Authentication Method"), ALT+Key_A, plugMenu );
+		inserten( i18n("&Authentication Method"), 0, plugMenu );
 		needSep = true;
 	}
 
 #ifdef XDMCP
-	completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), ALT+Key_R );
+	completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), 0 );
 #else
 	completeMenu();
 #endif
 
+        if (userView || userList)
+		insertUsers();
+
 	if (optMenu)
 		menuButton->setPopup( optMenu );
 	else
@@ -826,6 +971,9 @@ KThemedGreeter::KThemedGreeter()
 	if (xauth_warning && (_authorized || !_authComplain))
 		xauth_warning->hide( true );
 
+        if (userView || userList)
+            insertUsers( 7 ); // TODO: find out how many are a good value
+
 //	if (!_greetString.isEmpty()) {
 //	}
 //	clock = new KdmClock( this, "clock" );
@@ -851,12 +999,8 @@ KThemedGreeter::KThemedGreeter()
 	if ((itm = themer->findNode( "session_button" ))) {
 		if (sessMenu->count() <= 1)
 			itm->hide( true );
-		else {
+                else
 			session_button = itm;
-			TQAccel *accel = new TQAccel( this );
-			accel->insertItem( ALT+Key_T, 0 );
-			connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotSessMenu()) );
-		}
 	} else {
 		if (sessMenu->count() > 1) {
 			inserten( i18n("Session &Type"), ALT+Key_T, sessMenu );
@@ -864,6 +1008,12 @@ KThemedGreeter::KThemedGreeter()
 		}
 	}
 
+	admin_button = themer->findNode( "admin_button");
+	if ( admin_button ) {
+	  if ( !_useAdminSession )
+	    admin_button->hide( true );
+	}
+
 	if (plugMenu) {
 		inserten( i18n("&Authentication Method"), ALT+Key_A, plugMenu );
 		needSep = true;
@@ -899,8 +1049,8 @@ KThemedGreeter::pluginSetup()
 	inherited::pluginSetup();
 
 	if (userView && verify->entitiesLocal() && verify->entityPresettable() && userlist_rect) {
+		userView->setMaximumHeight( userView->sumHeight() );
 		userlist_rect->setWidget( userView );
-		userView->show();
 	} else {
 		if (userView)
 			userView->hide();
@@ -916,12 +1066,17 @@ KThemedGreeter::verifyFailed()
 {
 //	goButton->setEnabled( false );
 	inherited::verifyFailed();
+	if (userView)
+		userView->setEnabled(false);
 }
 
 void
 KThemedGreeter::verifyRetry()
 {
 //	goButton->setEnabled( true );
+        if (userView)
+                userView->setEnabled(true);
+
 }
 
 TQString KThemedGreeter::timedUser = TQString::null;
@@ -966,6 +1121,8 @@ KThemedGreeter::slotThemeActivated( const TQString &id )
 		slotSessMenu();
 	else if (id == "system_button")
 		slotActionMenu();
+	else if (id == "admin_button")
+	        slotAskAdminPassword();
 }
 
 void
@@ -992,4 +1149,15 @@ KThemedGreeter::keyPressEvent( TQKeyEvent *e )
 		accept();
 }
 
+void
+KThemedGreeter::slotAskAdminPassword()
+{
+  KDMAdmin k(curUser, this);
+  if (k.exec()) {
+	GSendInt(G_Ready);
+	hide();
+	done(ex_exit);
+   }
+}
+
 #include "kgreeter.moc"
diff --git a/kdm/kfrontend/kgreeter.h b/kdm/kfrontend/kgreeter.h
index 61673badf..fdbd56209 100644
--- a/kdm/kfrontend/kgreeter.h
+++ b/kdm/kfrontend/kgreeter.h
@@ -73,9 +73,10 @@ class KGreeter : public KGDialog, public KGVerifyHandler {
 	void slotUserEntered();
 
   protected:
+        void readFacesList();
 	void installUserList();
 	void insertUser( const TQImage &, const TQString &, struct passwd * );
-	void insertUsers();
+	void insertUsers( int limit = -1);
 	void putSession( const TQString &, const TQString &, bool, const char * );
 	void insertSessions();
 	virtual void pluginSetup();
@@ -87,10 +88,13 @@ class KGreeter : public KGDialog, public KGVerifyHandler {
 	TQStringList *userList;
 	TQPopupMenu *sessMenu;
 	TQValueVector<SessType> sessionTypes;
+        TQStringList randomFaces;
+        TQMap<TQString, TQString> randomFacesMap;
 	int nNormals, nSpecials;
 	int curPrev, curSel;
 	bool prevValid;
 	bool needLoad;
+        bool themed;
 
 	static int curPlugin;
 	static PluginList pluginList;
@@ -142,6 +146,7 @@ class KThemedGreeter : public KGreeter {
 	void slotThemeActivated( const TQString &id );
 	void slotSessMenu();
 	void slotActionMenu();
+	void slotAskAdminPassword();
 
   protected:
 	virtual void updateStatus( bool fail, bool caps, int timedleft );
@@ -154,7 +159,7 @@ class KThemedGreeter : public KGreeter {
 	KdmThemer *themer;
 	KdmItem *caps_warning, *xauth_warning, *pam_error, *timed_label,
 	        *console_rect, *userlist_rect,
-	        *session_button, *system_button;
+	        *session_button, *system_button, *admin_button;
 
   public: // from KGVerifyHandler
 	virtual void verifyFailed();
diff --git a/kdm/kfrontend/sessions/Makefile.am b/kdm/kfrontend/sessions/Makefile.am
index 14577ac42..71655c9a4 100644
--- a/kdm/kfrontend/sessions/Makefile.am
+++ b/kdm/kfrontend/sessions/Makefile.am
@@ -1,6 +1,6 @@
 sessionsdir = $(kde_datadir)/kdm/sessions
 sessions_DATA = \
-    kde.desktop gnome.desktop \
+    admin.desktop kde.desktop gnome.desktop \
     9wm.desktop \
     aewm++.desktop \
     aewm.desktop \
diff --git a/kdm/kfrontend/sessions/admin.desktop b/kdm/kfrontend/sessions/admin.desktop
new file mode 100644
index 000000000..73e6ae3bf
--- /dev/null
+++ b/kdm/kfrontend/sessions/admin.desktop
@@ -0,0 +1,7 @@
+[Desktop Entry]
+Encoding=UTF-8
+Type=XSession
+Exec=YaSTadminSession
+TryExec=YaSTadminSession
+Name=admin
+Comment=Yast Admin Session
diff --git a/kdm/kfrontend/themer/kdmitem.cpp b/kdm/kfrontend/themer/kdmitem.cpp
index 38af9d0aa..d47c0242d 100644
--- a/kdm/kfrontend/themer/kdmitem.cpp
+++ b/kdm/kfrontend/themer/kdmitem.cpp
@@ -23,10 +23,11 @@
  * Generic Kdm Item
  */
 
-//#define DRAW_OUTLINE 1	// for debugging only
+// #define DRAW_OUTLINE 1	// for debugging only
 
 #include "kdmitem.h"
 #include "kdmlayout.h"
+#include "kdmconfig.h"
 
 #include <kglobal.h>
 #include <kdebug.h>
@@ -35,9 +36,7 @@
 #include <tqwidget.h>
 #include <tqlayout.h>
 #include <tqimage.h>
-#ifdef DRAW_OUTLINE
-# include <tqpainter.h>
-#endif
+#include <tqpainter.h>
 
 KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name )
     : TQObject( parent, name )
@@ -47,6 +46,25 @@ KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name )
     , myWidget( 0 )
     , myLayoutItem( 0 )
     , buttonParent( 0 )
+{
+  init(node, name);
+}
+
+
+KdmItem::KdmItem( TQWidget *parent, const TQDomNode &node, const char *name )
+    : TQObject( parent, name )
+    , boxManager( 0 )
+    , fixedManager( 0 )
+    , image( 0 )
+    , myWidget( 0 )
+    , myLayoutItem( 0 )
+    , buttonParent( 0 )
+{
+  init(node, name);
+}
+
+void
+KdmItem::init( const TQDomNode &node, const char * )
 {
 	// Set default layout for every item
 	currentManager = MNone;
@@ -62,7 +80,7 @@ KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name )
 	state = Snormal;
 
 	// The "toplevel" node (the screen) is really just like a fixed node
-	if (!parent || !parent->inherits( "KdmItem" )) {
+	if (!parent() || !parent()->inherits( "KdmItem" )) {
 		setFixedLayout();
 		return;
 	}
@@ -87,7 +105,7 @@ KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name )
 	id = tnode.toElement().attribute( "id", TQString::number( (ulong)this, 16 ) );
 
 	// Tell 'parent' to add 'me' to its children
-	KdmItem *parentItem = static_cast<KdmItem *>( parent );
+	KdmItem *parentItem = static_cast<KdmItem *>( parent() );
 	parentItem->addChildItem( this );
 }
 
@@ -195,7 +213,7 @@ KdmItem::setWidget( TQWidget *widget )
 	if (frame)
 		frame->setFrameStyle( TQFrame::NoFrame );
 
-	myWidget->setGeometry(area);
+	setGeometry(area, true);
 
 	connect( myWidget, TQT_SIGNAL(destroyed()), TQT_SLOT(widgetGone()) );
 }
@@ -236,15 +254,21 @@ KdmItem::setGeometry( const TQRect &newGeometry, bool force )
 
 	area = newGeometry;
 
-	if (myWidget)
-		myWidget->setGeometry( newGeometry );
+	if (myWidget) {
+            TQRect widGeo = newGeometry;
+            if ( widGeo.height() > myWidget->maximumHeight() ) {
+                widGeo.moveTop( widGeo.top() + ( widGeo.height() -  myWidget->maximumHeight() ) / 2 );
+                widGeo.setHeight( myWidget->maximumHeight() );
+            }
+            myWidget->setGeometry( widGeo );
+        }
 	if (myLayoutItem)
 		myLayoutItem->setGeometry( newGeometry );
 
 	// recurr to all boxed children
 	if (boxManager && !boxManager->isEmpty())
 		boxManager->update( newGeometry, force );
-
+ 
 	// recurr to all fixed children
 	if (fixedManager && !fixedManager->isEmpty())
 		fixedManager->update( newGeometry, force );
@@ -258,8 +282,16 @@ KdmItem::paint( TQPainter *p, const TQRect &rect )
 	if (isHidden())
 		return;
 
-	if (myWidget || (myLayoutItem && myLayoutItem->widget()))
-		return;
+	if (myWidget || (myLayoutItem && myLayoutItem->widget())) {
+            // KListView because it's missing a Q_OBJECT
+            if ( myWidget && myWidget->isA( "KListView" ) ) {
+                TQPixmap copy( myWidget->size() );
+                kdDebug() <<  myWidget->geometry() << " " << area << " " << myWidget->size() << endl;
+                bitBlt( &copy, TQPoint( 0, 0), p->device(), myWidget->geometry(), Qt::CopyROP );
+                myWidget->setPaletteBackgroundPixmap( copy );
+            }
+            return;
+        }
 
 	if (area.intersects( rect )) {
 		TQRect contentsRect = area.intersect( rect );
@@ -280,6 +312,8 @@ KdmItem::paint( TQPainter *p, const TQRect &rect )
 	TQValueList<KdmItem *>::Iterator it;
 	for (it = m_children.begin(); it != m_children.end(); ++it)
 		(*it)->paint( p, rect );
+
+
 }
 
 KdmItem *KdmItem::currentActive = 0;
@@ -287,8 +321,11 @@ KdmItem *KdmItem::currentActive = 0;
 void
 KdmItem::mouseEvent( int x, int y, bool pressed, bool released )
 {
+	if (isShown == ExplicitlyHidden)
+		return;
+
 	if (buttonParent && buttonParent != this) {
-		buttonParent->mouseEvent( x, y, pressed, released );
+	        buttonParent->mouseEvent( x, y, pressed, released );
 		return;
 	}
 
@@ -362,7 +399,8 @@ KdmItem::placementHint( const TQRect &parentRect )
 	    w = parentRect.width(),
 	    h = parentRect.height();
 
-	kdDebug() << "KdmItem::placementHint parentRect=" << id << parentRect << " hintedSize=" << hintedSize << endl;
+	kdDebug() << timestamp() << " KdmItem::placementHint parentRect=" << parentRect << " hintedSize=" << hintedSize << endl;
+
 	// check if width or height are set to "box"
 	if (pos.wType == DTbox || pos.hType == DTbox) {
 		if (myLayoutItem || myWidget)
@@ -372,7 +410,7 @@ KdmItem::placementHint( const TQRect &parentRect )
 				return parentRect;
 			boxHint = boxManager->sizeHint();
 		}
-		kdDebug() << " => boxHint " << boxHint << endl;
+		kdDebug() << timestamp() << " boxHint " << boxHint << endl;
 	}
 
 	if (pos.xType == DTpixel)
@@ -380,25 +418,25 @@ KdmItem::placementHint( const TQRect &parentRect )
 	else if (pos.xType == DTnpixel)
 		x = parentRect.right() - pos.x;
 	else if (pos.xType == DTpercent)
-		x += int( parentRect.width() / 100.0 * pos.x );
+		x += qRound( parentRect.width() / 100.0 * pos.x );
 
 	if (pos.yType == DTpixel)
 		y += pos.y;
 	else if (pos.yType == DTnpixel)
 		y = parentRect.bottom() - pos.y;
 	else if (pos.yType == DTpercent)
-		y += int( parentRect.height() / 100.0 * pos.y );
+		y += qRound( parentRect.height() / 100.0 * pos.y );
 
 	if (pos.wType == DTpixel)
 		w = pos.width;
 	else if (pos.wType == DTnpixel)
 		w -= pos.width;
 	else if (pos.wType == DTpercent)
-		w = int( parentRect.width() / 100.0 * pos.width );
+		w = qRound( parentRect.width() / 100.0 * pos.width );
 	else if (pos.wType == DTbox)
 		w = boxHint.width();
 	else if (hintedSize.width() > 0)
-		w = hintedSize.width();
+	        w = hintedSize.width();
 	else
 		w = 0;
 
@@ -407,14 +445,22 @@ KdmItem::placementHint( const TQRect &parentRect )
 	else if (pos.hType == DTnpixel)
 		h -= pos.height;
 	else if (pos.hType == DTpercent)
-		h = int( parentRect.height() / 100.0 * pos.height );
+		h = qRound( parentRect.height() / 100.0 * pos.height );
 	else if (pos.hType == DTbox)
 		h = boxHint.height();
-	else if (hintedSize.height() > 0)
-		h = hintedSize.height();
-	else
+	else if (hintedSize.height() > 0) {
+	        if (w && pos.wType != DTnone)
+	               h = (hintedSize.height() * w) / hintedSize.width();
+	        else
+	               h = hintedSize.height();
+	} else
 		h = 0;
 
+	// we choose to take the hinted size, but it's better to listen to the aspect ratio
+	if (pos.wType == DTnone && pos.hType != DTnone && h && w) {
+	        w = qRound(float(hintedSize.width() * h) / hintedSize.height());
+	}
+
 	// defaults to center
 	int dx = -w / 2, dy = -h / 2;
 
@@ -430,7 +476,7 @@ KdmItem::placementHint( const TQRect &parentRect )
 			dx = -w;
 	}
 	// KdmItem *p = static_cast<KdmItem*>( parent() );
-	kdDebug() << "KdmItem::placementHint " << id << " x=" << x << " dx=" << dx << " w=" << w << " y=" << y << " dy=" << dy << " h=" << h << " " << parentRect << endl;
+	kdDebug() << timestamp() << " placementHint " << this << " x=" << x << " dx=" << dx << " w=" << w << " y=" << y << " dy=" << dy << " h=" << h << " " << parentRect << endl;
 	y += dy;
 	x += dx;
 
@@ -529,4 +575,17 @@ KdmItem::setFixedLayout( const TQDomNode &node )
 	currentManager = MFixed;
 }
 
+TQWidget *
+KdmItem::parentWidget() const
+{
+  if (myWidget)
+    return myWidget;
+  if (!this->parent())
+    return 0;
+
+  if (parent()->qt_cast("TQWidget"))
+    return (TQWidget*)parent();
+  return ((KdmItem*)parent())->parentWidget();
+}
+
 #include "kdmitem.moc"
diff --git a/kdm/kfrontend/themer/kdmitem.h b/kdm/kfrontend/themer/kdmitem.h
index 6a73c889f..98b876977 100644
--- a/kdm/kfrontend/themer/kdmitem.h
+++ b/kdm/kfrontend/themer/kdmitem.h
@@ -90,6 +90,8 @@ public:
 	 * Item constructor and destructor
 	 */
 	KdmItem( KdmItem *parent, const TQDomNode &node = TQDomNode(), const char *name = 0 );
+	KdmItem( TQWidget *parent, const TQDomNode &node = TQDomNode(), const char *name = 0 ); // for the root
+
 	virtual ~KdmItem();
 
 	/**
@@ -151,6 +153,7 @@ public:
 
 	KdmItem *findNode( const TQString &id ) const;
 	virtual void setWidget( TQWidget *widget );
+	TQWidget *widget() const { return myWidget; }
 	virtual void setLayoutItem( TQLayoutItem *item );
 
 	virtual void hide( bool force = false );
@@ -160,6 +163,9 @@ public:
 	bool isExplicitlyHidden() const { return isShown == ExplicitlyHidden; }
 	TQRect rect() const { return area; }
 
+	TQWidget *parentWidget() const;
+	TQString getId() const { return id; }
+
 signals:
 	void needUpdate( int x, int y, int w, int h );
 	void activated( const TQString &id );
@@ -237,6 +243,7 @@ protected:
 	void parseColor( const TQString &, TQColor & );
 
 	void inheritFromButton( KdmItem *button );
+	void init( const TQDomNode &node = TQDomNode(), const char *name = 0 );
 
 	TQString itemType, id;
 	TQValueList<KdmItem *> m_children;
diff --git a/kdm/kfrontend/themer/kdmlabel.cpp b/kdm/kfrontend/themer/kdmlabel.cpp
index 297b7cc48..e83ae9dc7 100644
--- a/kdm/kfrontend/themer/kdmlabel.cpp
+++ b/kdm/kfrontend/themer/kdmlabel.cpp
@@ -19,8 +19,10 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
+#include <config.h>
 #include "kdmlabel.h"
-#include <kgreeter.h>
+#include "kdmconfig.h"
+#include "../kgreeter.h"
 
 #include <kglobal.h>
 #include <klocale.h>
@@ -31,6 +33,7 @@
 #include <tqpainter.h>
 #include <tqfontmetrics.h>
 #include <tqtimer.h>
+#include <tqaccel.h>
 
 #include <unistd.h>
 #include <sys/utsname.h>
@@ -39,7 +42,7 @@
 #endif
 
 KdmLabel::KdmLabel( KdmItem *parent, const TQDomNode &node, const char *name )
-    : KdmItem( parent, node, name )
+       : KdmItem( parent, node, name ), myAccel(0)
 {
 	itemType = "label";
 
@@ -92,21 +95,46 @@ KdmLabel::KdmLabel( KdmItem *parent, const TQDomNode &node, const char *name )
 		}
 	}
 
-	// Check if this is a timer label
+	// Check if this is a timer label)
 	label.isTimer = label.text.find( "%c" ) >= 0;
 	if (label.isTimer) {
 		timer = new TQTimer( this );
 		timer->start( 1000 );
 		connect( timer, TQT_SIGNAL(timeout()), TQT_SLOT(update()) );
 	}
-	cText = lookupText( label.text );
+	setTextInt( lookupText( label.text ) );
+}
+
+void
+KdmLabel::setTextInt( const TQString &txt)
+{
+  // TODO: catch &&
+        cText = txt;
+	cAccel = txt.find('&');
+	delete myAccel;
+	myAccel = 0;
+	if (cAccel != -1) {
+	  cText.remove('&');
+	  myAccel = new TQAccel(parentWidget());
+	  myAccel->insertItem(ALT + UNICODE_ACCEL + cText.at(cAccel).lower().unicode());
+	  connect(myAccel, TQT_SIGNAL(activated(int)), TQT_SLOT(slotAccel()));
+	}
+}
+
+void
+KdmLabel::slotAccel()
+{
+  if (buttonParent)
+    emit activated(buttonParent->getId());
+  else
+    emit activated(id);
 }
 
 void
 KdmLabel::setText( const TQString &txt )
 {
 	label.text = txt;
-	update();
+	setTextInt( lookupText( label.text ) );
 }
 
 QSize
@@ -139,7 +167,23 @@ KdmLabel::drawContents( TQPainter *p, const TQRect &/*r*/  )
 	p->setFont( l->font );
 	p->setPen( l->color );
 	//TODO paint clipped (tested but not working..)
-	p->drawText( area, AlignLeft | SingleLine, cText );
+        if (cAccel != -1 && (!id.isEmpty() || buttonParent) ) {
+	  TQString left = cText.left(cAccel);
+	  TQString right = cText.mid(cAccel + 1);
+	  p->drawText( area, AlignLeft | SingleLine, left );
+	  TQRect tarea = area;
+	  TQFontMetrics fm(l->font);
+	  tarea.rLeft() += fm.width(left);
+	  TQFont f(l->font);
+	  f.setUnderline(true);
+	  p->setFont ( f );
+	  p->drawText( tarea, AlignLeft | SingleLine, TQString(cText.at(cAccel)));
+	  tarea.rLeft() += fm.width(cText.at(cAccel));
+	  p->setFont( l->font );
+	  p->drawText( tarea, AlignLeft | SingleLine, right);
+        } else {
+	  p->drawText( area, AlignLeft | SingleLine, cText);
+	}
 }
 
 void
@@ -159,7 +203,7 @@ KdmLabel::update()
 {
 	TQString text = lookupText( label.text );
 	if (text != cText) {
-		cText = text;
+	        setTextInt(text);
 		needUpdate();
 	}
 }
@@ -170,18 +214,20 @@ static const struct {
 	{ "language",           I18N_NOOP("Language") },
 	{ "session",            I18N_NOOP("Session Type") },
 	{ "system",             I18N_NOOP("Menu") },	// i18n("Actions");
+        { "admin",              I18N_NOOP("&Administration") },
 	{ "disconnect",         I18N_NOOP("Disconnect") },
 	{ "quit",               I18N_NOOP("Quit") },
-	{ "halt",               I18N_NOOP("Power off") },
+	{ "halt",               I18N_NOOP("Power Off") },
 	{ "suspend",            I18N_NOOP("Suspend") },
 	{ "reboot",             I18N_NOOP("Reboot") },
 	{ "chooser",            I18N_NOOP("XDMCP Chooser") },
 	{ "config",             I18N_NOOP("Configure") },
-	{ "caps-lock-warning",  I18N_NOOP("You have got caps lock on.") },
+	{ "caps-lock-warning",  I18N_NOOP("Caps Lock is enabled.") },
 	{ "timed-label",        I18N_NOOP("User %s will login in %d seconds") },
 	{ "welcome-label",      I18N_NOOP("Welcome to %h") },	// _greetString
 	{ "username-label",     I18N_NOOP("Username:") },
 	{ "password-label",     I18N_NOOP("Password:") },
+        { "domain-label",       I18N_NOOP("Domain:") },
 	{ "login",              I18N_NOOP("Login") }
 };
 
@@ -195,7 +241,7 @@ KdmLabel::lookupStock( const TQString &stock )
 		if (type == stocks[i].type)
 			return i18n(stocks[i].text);
 
-	kdDebug() << "Invalid <stock> element. Check your theme!" << endl;
+	kdDebug() << timestamp() << " Invalid <stock> element. Check your theme!" << endl;
 	return stock;
 }
 
@@ -205,7 +251,6 @@ KdmLabel::lookupText( const TQString &t )
 	TQString text = t;
 
 	text.replace( '_', '&' );
-//	text.remove( '_' ); // FIXME add key accels, remove underscores for now
 
 	TQMap<TQChar,TQString> m;
 	struct utsname uts;
diff --git a/kdm/kfrontend/themer/kdmlabel.h b/kdm/kfrontend/themer/kdmlabel.h
index 0770259c0..1ec2f88ec 100644
--- a/kdm/kfrontend/themer/kdmlabel.h
+++ b/kdm/kfrontend/themer/kdmlabel.h
@@ -50,6 +50,7 @@ protected:
 	// handle switching between normal / active / prelight configurations
 	virtual void statusChanged();
 
+public:
 	struct LabelStruct {
 		TQString text;
 		bool isTimer;
@@ -67,6 +68,7 @@ protected:
 
 public slots:
 	void update();
+	void slotAccel();
 
 private:
 	/* Method to lookup the caption associated with an item */
@@ -76,6 +78,10 @@ private:
 	TQString lookupText( const TQString &t );
 
 	TQString cText;
+	int cAccel;
+	TQAccel *myAccel;
+
+	void setTextInt(const TQString &);
 };
 
 #endif
diff --git a/kdm/kfrontend/themer/kdmlayout.cpp b/kdm/kfrontend/themer/kdmlayout.cpp
index 00ca693ae..b17d2e7b7 100644
--- a/kdm/kfrontend/themer/kdmlayout.cpp
+++ b/kdm/kfrontend/themer/kdmlayout.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "kdmlayout.h"
+#include "kdmconfig.h"
 #include "kdmitem.h"
 
 #include <kdebug.h>
@@ -35,11 +36,11 @@ KdmLayoutFixed::KdmLayoutFixed( const TQDomNode &/*node*/ )
 void
 KdmLayoutFixed::update( const TQRect &parentGeometry, bool force )
 {
-	kdDebug() << "KdmLayoutFixed::update " << parentGeometry << endl;
+	kdDebug() << timestamp() << " KdmLayoutFixed::update " << parentGeometry << endl;
 
 	// I can't layout children if the parent rectangle is not valid
 	if (parentGeometry.width() < 0 || parentGeometry.height() < 0) {
-		kdDebug() << "invalid\n";
+		kdDebug() << timestamp() << " invalid\n";
 		return;
 	}
 	// For each child in list I ask their hinted size and set it!
@@ -102,7 +103,7 @@ KdmLayoutBox::update( const TQRect &parentGeometry, bool force )
 				childrenRect.setTop( childrenRect.top() + height + box.spacing );
 			} else {
 				TQRect temp( childrenRect.left(), childrenRect.top(), width, childrenRect.height() );
-				kdDebug() << "placement " << *it << " " << temp << " " << (*it)->placementHint( temp ) << endl;
+				kdDebug() << timestamp() << " placement " << *it << " " << temp << " " << (*it)->placementHint( temp ) << endl;
 				temp = (*it)->placementHint( temp );
 				(*it)->setGeometry( temp, force );
 				childrenRect.setLeft( childrenRect.left() + width + box.spacing );
@@ -125,7 +126,7 @@ KdmLayoutBox::update( const TQRect &parentGeometry, bool force )
 				kdDebug() << this << " placementHint " << *it << " " << temp << " " << itemRect << endl;
 				temp.setWidth( itemRect.width() );
 				childrenRect.setLeft( childrenRect.left() + itemRect.size().width() + box.spacing );
-				kdDebug() << "childrenRect after " << *it << " " << childrenRect << endl;
+				kdDebug() << timestamp() << " childrenRect after " << *it << " " << childrenRect << endl;
 			}
 			itemRect = (*it)->placementHint( temp );
 			kdDebug() << this << " placementHint2 " << *it << " " << temp << " " << itemRect << endl;
diff --git a/kdm/kfrontend/themer/kdmpixmap.cpp b/kdm/kfrontend/themer/kdmpixmap.cpp
index 07077e4a1..f18194f53 100644
--- a/kdm/kfrontend/themer/kdmpixmap.cpp
+++ b/kdm/kfrontend/themer/kdmpixmap.cpp
@@ -22,6 +22,7 @@
 #include <config.h>
 
 #include "kdmpixmap.h"
+#include <kdmconfig.h>
 
 #include <kimageeffect.h>
 #ifdef HAVE_LIBART
@@ -29,6 +30,7 @@
 #endif
 
 #include <kdebug.h>
+#include <kstandarddirs.h>
 
 #include <tqpainter.h>
 #include <tqpixmap.h>
@@ -58,21 +60,28 @@ KdmPixmap::KdmPixmap( KdmItem *parent, const TQDomNode &node, const char *name )
 		TQString tagName = el.tagName();
 
 		if (tagName == "normal") {
-			loadPixmap( el.attribute( "file", "" ), pixmap.normal.pixmap, pixmap.normal.fullpath );
+			pixmap.normal.fullpath = fullPath( el.attribute( "file", "" ) );
 			parseColor( el.attribute( "tint", "#ffffff" ), pixmap.normal.tint );
 			pixmap.normal.alpha = el.attribute( "alpha", "1.0" ).toFloat();
 		} else if (tagName == "active") {
 			pixmap.active.present = true;
-			loadPixmap( el.attribute( "file", "" ), pixmap.active.pixmap, pixmap.active.fullpath );
+			pixmap.active.fullpath = fullPath( el.attribute( "file", "" ) );
 			parseColor( el.attribute( "tint", "#ffffff" ), pixmap.active.tint );
 			pixmap.active.alpha = el.attribute( "alpha", "1.0" ).toFloat();
 		} else if (tagName == "prelight") {
 			pixmap.prelight.present = true;
-			loadPixmap( el.attribute( "file", "" ), pixmap.prelight.pixmap, pixmap.prelight.fullpath );
+			pixmap.prelight.fullpath = fullPath(el.attribute( "file", "" ) );
 			parseColor( el.attribute( "tint", "#ffffff" ), pixmap.prelight.tint );
 			pixmap.prelight.alpha = el.attribute( "alpha", "1.0" ).toFloat();
 		}
 	}
+
+	// look if we have to have the aspect ratio ready
+	if (((pos.wType == DTnone && pos.hType != DTnone) ||
+	     (pos.wType != DTnone && pos.hType == DTnone) ||
+	     (pos.wType == DTnone && pos.hType == DTnone)) &&
+	    !pixmap.normal.fullpath.endsWith( ".svg" ))
+	  loadPixmap( &pixmap.normal );
 }
 
 QSize
@@ -100,19 +109,16 @@ KdmPixmap::setGeometry( const TQRect &newGeometry, bool force )
 }
 
 
-void
-KdmPixmap::loadPixmap( const TQString &fileName, TQPixmap &map, TQString &fullName )
+TQString
+KdmPixmap::fullPath( const TQString &fileName)
 {
-	if (fileName.isEmpty())
-		return;
+        if (fileName.isEmpty())
+		return TQString::null;
 
-	fullName = fileName;
+	TQString fullName = fileName;
 	if (fullName.at( 0 ) != '/')
 		fullName = baseDir() + "/" + fileName;
-
-	if (!fullName.endsWith( ".svg" ))	// we delay it for svgs
-		if (!map.load( fullName ))
-			fullName = TQString::null;
+	return fullName;
 }
 
 void
@@ -139,6 +145,25 @@ KdmPixmap::renderSvg( PixmapStruct::PixmapClass *pClass, const TQRect &area )
 #endif
 }
 
+void
+KdmPixmap::loadPixmap( PixmapStruct::PixmapClass *pClass )
+{
+  TQString fullpath = pClass->fullpath;
+
+  kdDebug() << timestamp() << " load " << fullpath << endl;
+  int index = fullpath.findRev('.');
+  TQString ext = fullpath.right(fullpath.length() - index);
+  fullpath = fullpath.left(index);
+  kdDebug() << timestamp() << " ext " << ext << " " << fullpath << endl;
+  TQString testpath = TQString("-%1x%2").arg(area.width()).arg(area.height()) + ext;
+  kdDebug() << timestamp() << " testing for " << fullpath + testpath << endl;
+  if (KStandardDirs::exists(fullpath + testpath)) 
+    pClass->pixmap.load(fullpath + testpath);
+  else
+    pClass->pixmap.load( fullpath + ext );
+  kdDebug() << timestamp() << " done\n";
+}
+
 void
 KdmPixmap::drawContents( TQPainter *p, const TQRect &r )
 {
@@ -149,12 +174,20 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r )
 	if (state == Sprelight && pixmap.prelight.present)
 		pClass = &pixmap.prelight;
 
+	kdDebug() << "draw " << id << " " << pClass->pixmap.isNull() << endl;
+ 
 	if (pClass->pixmap.isNull()) {
-		if (pClass->fullpath.isEmpty())	// if neither is set, we're empty
+	        
+	        if (pClass->fullpath.isEmpty())	// if neither is set, we're empty
 			return;
-
-		kdDebug() << "renderSVG\n";
-		renderSvg( pClass, area );
+		
+		if (!pClass->fullpath.endsWith( ".svg" ) ) {
+		  loadPixmap(pClass);
+		} else {
+		  kdDebug() << timestamp() << " renderSVG\n";
+		  renderSvg( pClass, area );
+		  kdDebug() << timestamp() << " done\n";
+		}
 	}
 
 	int px = area.left() + r.left();
@@ -176,25 +209,37 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r )
 
 
 	if (pClass->readyPixmap.isNull()) {
-		TQImage scaledImage;
+	  
+		bool haveTint = pClass->tint.rgb() != 0xFFFFFF;
+		bool haveAlpha = pClass->alpha < 1.0;
 
+		TQImage scaledImage;
+		
 		// use the loaded pixmap or a scaled version if needed
 
+		kdDebug() << timestamp() << " prepare readyPixmap " << pClass->fullpath << " " << area.size() << " " << pClass->pixmap.size() << endl;
 		if (area.size() != pClass->pixmap.size()) {
 			if (pClass->fullpath.endsWith( ".svg" )) {
-				kdDebug() << "renderSVG\n";
+				kdDebug() << timestamp() << " renderSVG\n";
 				renderSvg( pClass, area );
 				scaledImage = pClass->pixmap.convertToImage();
 			} else {
-				kdDebug() << "convertFromImage\n";
+				kdDebug() << timestamp() << " convertFromImage smoothscale\n";
 				TQImage tempImage = pClass->pixmap.convertToImage();
+				kdDebug() << timestamp() << " convertToImage done\n";
 				scaledImage = tempImage.smoothScale( area.width(), area.height() );
+				kdDebug() << timestamp() << " done\n";
 			}
-		} else
+		} else {
+		  if (haveTint || haveAlpha)
+                  {
 			scaledImage = pClass->pixmap.convertToImage();
-
-		bool haveTint = pClass->tint.rgb() != 0xFFFFFF;
-		bool haveAlpha = pClass->alpha < 1.0;
+                        // enforce rgba values for the later
+                        scaledImage = scaledImage.convertDepth( 32 );
+                  }
+		  else
+		    pClass->readyPixmap = pClass->pixmap;
+		}
 
 		if (haveTint || haveAlpha) {
 			// blend image(pix) with the given tint
@@ -221,9 +266,12 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r )
 
 		}
 
-		pClass->readyPixmap.convertFromImage( scaledImage );
+		if (!scaledImage.isNull()) {
+		  kdDebug() << timestamp() << " convertFromImage " << id << " " << area << endl;
+		  pClass->readyPixmap.convertFromImage( scaledImage );
+		}
 	}
-	// kdDebug() << "Pixmap::drawContents " << pClass->readyPixmap.size() << " " << px << " " << py << " " << sx << " " << sy << " " << sw << " " << sh << endl;
+	kdDebug() << timestamp() << " Pixmap::drawContents " << pClass->readyPixmap.size() << " " << px << " " << py << " " << sx << " " << sy << " " << sw << " " << sh << endl;
 	p->drawPixmap( px, py, pClass->readyPixmap, sx, sy, sw, sh );
 }
 
diff --git a/kdm/kfrontend/themer/kdmpixmap.h b/kdm/kfrontend/themer/kdmpixmap.h
index 479ef0f8d..92d4895d0 100644
--- a/kdm/kfrontend/themer/kdmpixmap.h
+++ b/kdm/kfrontend/themer/kdmpixmap.h
@@ -61,9 +61,10 @@ protected:
 	} pixmap;
 
 private:
-	// Method to load the pixmap given by the theme
-	void loadPixmap( const TQString &fileName, TQPixmap &p, TQString &path );
+	// Method to load the pixmap path given by the theme
+	TQString fullPath( const TQString &fileName );
 	void renderSvg( PixmapStruct::PixmapClass *pClass, const TQRect &area );
+	void loadPixmap( PixmapStruct::PixmapClass *pClass );
 };
 
 #endif
diff --git a/kdm/kfrontend/themer/kdmrect.cpp b/kdm/kfrontend/themer/kdmrect.cpp
index 961809a37..1d854d213 100644
--- a/kdm/kfrontend/themer/kdmrect.cpp
+++ b/kdm/kfrontend/themer/kdmrect.cpp
@@ -32,6 +32,18 @@
 
 KdmRect::KdmRect( KdmItem *parent, const TQDomNode &node, const char *name )
     : KdmItem( parent, node, name )
+{
+  init( node, name );
+}
+
+KdmRect::KdmRect( TQWidget *parent, const TQDomNode &node, const char *name )
+    : KdmItem( parent, node, name )
+{
+  init( node, name );
+}
+
+void
+KdmRect::init( const TQDomNode &node, const char * )
 {
 	itemType = "rect";
 
@@ -136,13 +148,6 @@ KdmRect::recursiveSetAttribs( TQLayoutItem *li )
     }
 }
 
-void
-KdmRect::setWidget( TQWidget *widget )
-{
-	KdmItem::setWidget( widget );
-	setAttribs( widget );
-}
-
 void
 KdmRect::setLayoutItem( TQLayoutItem *item )
 {
@@ -151,4 +156,17 @@ KdmRect::setLayoutItem( TQLayoutItem *item )
 }
 */
 
+void
+KdmRect::setWidget( TQWidget *widget )
+{
+        if ( rect.normal.color.isValid() && widget ) 
+        {
+     	     TQPalette p = widget->palette();
+	     p.setColor( TQPalette::Normal, TQColorGroup::Text, rect.normal.color );
+	     widget->setPalette(p);
+	}
+	KdmItem::setWidget( widget );
+	//setAttribs( widget );
+}
+
 #include "kdmrect.moc"
diff --git a/kdm/kfrontend/themer/kdmrect.h b/kdm/kfrontend/themer/kdmrect.h
index 7e4776233..a505e1921 100644
--- a/kdm/kfrontend/themer/kdmrect.h
+++ b/kdm/kfrontend/themer/kdmrect.h
@@ -36,6 +36,7 @@ class KdmRect : public KdmItem {
 
 public:
 	KdmRect( KdmItem *parent, const TQDomNode &node, const char *name = 0 );
+	KdmRect( TQWidget *parent, const TQDomNode &node, const char *name = 0 );
 
 protected:
 	// draw the rect
@@ -54,8 +55,9 @@ protected:
 		bool hasBorder;
 	} rect;
 
-//	virtual void setWidget( TQWidget *widget );
+	virtual void setWidget( TQWidget *widget );
 //	virtual void setLayoutItem( TQLayoutItem *item );
+	void init( const TQDomNode &node, const char *name );
 
 private:
 	void setAttribs( TQWidget *widget );
diff --git a/kdm/kfrontend/themer/kdmthemer.cpp b/kdm/kfrontend/themer/kdmthemer.cpp
index aca43e45d..9e6db33db 100644
--- a/kdm/kfrontend/themer/kdmthemer.cpp
+++ b/kdm/kfrontend/themer/kdmthemer.cpp
@@ -36,11 +36,13 @@
 
 #include <tqfile.h>
 #include <tqfileinfo.h>
-//#include <tqtimer.h>		// animation timer - TODO
+#include <tqtimer.h>		// animation timer - TODO
 #include <tqobjectlist.h>
 #include <tqpainter.h>
 #include <tqwidget.h>
 #include <tqregion.h>
+#include <tqlineedit.h>
+#include <tqapplication.h>
 
 #include <unistd.h>
 
@@ -72,7 +74,8 @@ KdmThemer::KdmThemer( const TQString &_filename, const TQString &mode, TQWidget
 		return;
 	}
 	// Set the root (screen) item
-	rootItem = new KdmRect( 0, TQDomNode(), "kdm root" );
+	rootItem = new KdmRect( parent, TQDomNode(), "kdm root" );
+
 	connect( rootItem, TQT_SIGNAL(needUpdate( int, int, int, int )),
 	         widget(), TQT_SLOT(update( int, int, int, int )) );
 
@@ -82,6 +85,9 @@ KdmThemer::KdmThemer( const TQString &_filename, const TQString &mode, TQWidget
 	generateItems( rootItem );
 
 	connect( rootItem, TQT_SIGNAL(activated( const TQString & )), TQT_SIGNAL(activated( const TQString & )) );
+	connect( rootItem, TQT_SIGNAL(activated( const TQString & )), TQT_SLOT(slotActivated( const TQString & )) );
+
+	TQTimer::singleShot(800, this, TQT_SLOT(slotPaintRoot()));
 
 /*	*TODO*
 	// Animation timer
@@ -151,7 +157,7 @@ KdmThemer::widgetEvent( TQEvent *e )
 	case TQEvent::Paint:
 		{
 			TQRect paintRect = static_cast<TQPaintEvent *>(e)->rect();
-			kdDebug() << "paint on: " << paintRect << endl;
+			kdDebug() << timestamp() << " paint on: " << paintRect << endl;
 
 			if (!backBuffer)
 				backBuffer = new TQPixmap( widget()->size() );
@@ -195,7 +201,7 @@ KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node )
 
 		// Get its tag, and check it's correct ("greeter")
 		if (theme.tagName() != "greeter") {
-			kdDebug() << "This does not seem to be a correct theme file." << endl;
+			kdDebug() << timestamp() << " This does not seem to be a correct theme file." << endl;
 			return;
 		}
 		// Get the list of child nodes
@@ -214,6 +220,13 @@ KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node )
 		if (tagName == "item") {
 			if (!willDisplay( subnode ))
 				continue;
+			TQString id = el.attribute("id");
+			if (id.startsWith("plugin-specific-")) {
+			        id = id.mid(strlen("plugin-specific-"));
+			        if (!_pluginsLogin.contains(id))
+			               continue;
+			}
+
 			// It's a new item. Draw it
 			TQString type = el.attribute( "type" );
 
@@ -225,13 +238,11 @@ KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node )
 				newItem = new KdmPixmap( parent, subnode );
 			else if (type == "rect")
 				newItem = new KdmRect( parent, subnode );
-			else if (type == "entry") {
+			else if (type == "entry" || type == "list") {
 				newItem = new KdmRect( parent, subnode );
 				newItem->setType( type );
 			}
 			//	newItem = new KdmEntry( parent, subnode );
-			//else if (type=="list")
-			//	newItem = new KdmList( parent, subnode );
 			else if (type == "svg")
 				newItem = new KdmPixmap( parent, subnode );
 			if (newItem) {
@@ -287,6 +298,11 @@ bool KdmThemer::willDisplay( const TQDomNode &node )
 #endif
 	if (type == "halt" || type == "reboot")
 		return _allowShutdown != SHUT_NONE;
+        else if (type == "userlist")
+            return _userList;
+        else if ( type == "!userlist" )
+            return !_userList;
+
 //	if (type == "system")
 //		return true;
 
@@ -301,7 +317,7 @@ KdmThemer::showStructure( TQObject *obj )
 	const TQObjectList *wlist = obj->children();
 	static int counter = 0;
 	if (counter == 0)
-		kdDebug() << "\n\n<=======  Widget tree =================" << endl;
+		kdDebug() << timestamp() << " \n\n<=======  Widget tree =================" << endl;
 	if (wlist) {
 		counter++;
 		TQObjectListIterator it( *wlist );
@@ -323,7 +339,46 @@ KdmThemer::showStructure( TQObject *obj )
 		counter--;
 	}
 	if (counter == 0)
-		kdDebug() << "\n\n<=======  Widget tree =================\n\n" << endl;
+		kdDebug() << timestamp() << " \n\n<=======  Widget tree =================\n\n" << endl;
+}
+
+void
+KdmThemer::slotActivated( const TQString &id )
+{
+  TQString toactivate;
+  if (id == "username-label")
+    toactivate = "user-entry";
+  else if (id == "password-label")
+    toactivate = "pw-entry";
+  else
+    return;
+
+  KdmItem *item = findNode(toactivate);
+  if (!item || !item->widget())
+    return;
+
+  item->widget()->setFocus();
+  TQLineEdit *le = (TQLineEdit*)item->widget()->qt_cast("TQLineEdit");
+  if (le)
+    le->selectAll();
+}
+
+void
+KdmThemer::slotPaintRoot()
+{
+  KdmItem *back_item = findNode("background");
+  if (!back_item)
+    return;
+
+  TQRect screen = TQApplication::desktop()->screenGeometry(0);
+  TQPixmap pm(screen.size());
+
+  TQPainter painter( &pm, true );
+  back_item->paint( &painter, back_item->rect());
+  painter.end();
+
+  TQApplication::desktop()->screen()->setErasePixmap(pm);
+  TQApplication::desktop()->screen()->erase();
 }
 
 #include "kdmthemer.moc"
diff --git a/kdm/kfrontend/themer/kdmthemer.h b/kdm/kfrontend/themer/kdmthemer.h
index 6bf6af00d..6dc2318dd 100644
--- a/kdm/kfrontend/themer/kdmthemer.h
+++ b/kdm/kfrontend/themer/kdmthemer.h
@@ -80,6 +80,10 @@ public:
 signals:
 	void activated( const TQString &id );
 
+protected slots:
+	void slotActivated( const TQString &id );
+	void slotPaintRoot();
+
 private:
 	/*
 	 * Our display mode (e.g. console, remote, ...)
diff --git a/kdmlib/Makefile.am b/kdmlib/Makefile.am
index 91218a8c3..eedb681bc 100644
--- a/kdmlib/Makefile.am
+++ b/kdmlib/Makefile.am
@@ -1,11 +1,15 @@
 AM_CPPFLAGS = -I$(top_srcdir)/kdm/kfrontend $(all_includes)
 
-kde_module_LTLIBRARIES = kgreet_classic.la kgreet_winbind.la
+kde_module_LTLIBRARIES = kgreet_classic.la kgreet_pam.la kgreet_winbind.la
 
 kgreet_classic_la_SOURCES = kgreet_classic.cpp
 kgreet_classic_la_LDFLAGS = -module -no-undefined $(KDE_PLUGIN) $(all_libraries)
 kgreet_classic_la_LIBADD = $(LIB_KDEUI)
 
+kgreet_pam_la_SOURCES = kgreet_pam.cpp
+kgreet_pam_la_LDFLAGS = -module -no-undefined $(KDE_PLUGIN) $(all_libraries)
+kgreet_pam_la_LIBADD = $(LIB_KDEUI)
+
 kgreet_winbind_la_SOURCES = kgreet_winbind.cpp
 kgreet_winbind_la_LDFLAGS = -module -no-undefined $(KDE_PLUGIN) $(all_libraries)
 kgreet_winbind_la_LIBADD = $(LIB_KDEUI)
diff --git a/kdmlib/kgreet_pam.cpp b/kdmlib/kgreet_pam.cpp
new file mode 100644
index 000000000..b43952488
--- /dev/null
+++ b/kdmlib/kgreet_pam.cpp
@@ -0,0 +1,668 @@
+/*
+
+Conversation widget for kdm greeter
+
+Copyright (C) 2008 Dirk Mueller <mueller@kde.org>
+
+based on classic kdm greeter:
+
+  Copyright (C) 1997, 1998, 2000 Steffen Hansen <hansen@kde.org>
+  Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org>
+
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+*/
+
+#include "kgreet_pam.h"
+#include "themer/kdmthemer.h"
+#include "themer/kdmlabel.h"
+
+#include <klocale.h>
+#include <klineedit.h>
+#include <kpassdlg.h>
+#include <kuser.h>
+
+#include <tqregexp.h>
+#include <tqlayout.h>
+#include <tqlabel.h>
+#include <tqtimer.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <syslog.h>
+
+//#define PAM_GREETER_DEBUG
+
+class KDMPasswordEdit : public KPasswordEdit {
+public:
+	KDMPasswordEdit( TQWidget *parent ) : KPasswordEdit( parent, 0 ) {}
+	KDMPasswordEdit( KPasswordEdit::EchoModes echoMode, TQWidget *parent ) : KPasswordEdit( echoMode, parent, 0 ) {}
+protected:
+	virtual void contextMenuEvent( TQContextMenuEvent * ) {}
+};
+
+static FILE* log;
+static void debug(const char* fmt, ...)
+{
+    va_list lst;
+    va_start(lst, fmt);
+
+#ifdef PAM_GREETER_DEBUG
+#if 0
+    vfprintf(log, fmt, lst);
+    fflush(log);
+#else
+    char buf[6000];
+    sprintf(buf, "*** %s\n", fmt);
+    vsyslog(LOG_WARNING, buf, lst);
+#endif
+#endif
+    va_end(lst);
+}
+
+static KPasswordEdit::EchoModes echoMode;
+
+KPamGreeter::KPamGreeter( KGreeterPluginHandler *_handler,
+                                  KdmThemer *themer,
+                                  TQWidget *parent, TQWidget *pred,
+                                  const TQString &_fixedEntity,
+                                  Function _func, Context _ctx ) :
+	TQObject(),
+	KGreeterPlugin( _handler ),
+	fixedUser( _fixedEntity ),
+	func( _func ),
+	ctx( _ctx ),
+	exp( -1 ),
+	pExp( -1 ),
+	running( false )
+{
+        ctx = Login;
+
+        debug("KPamGreeter constructed\n");
+
+	m_parentWidget = parent;
+
+	KdmItem *user_entry = 0, *pw_entry = 0;
+	int line = 0;
+
+	layoutItem = 0;
+
+	if (themer &&
+	    (!(user_entry = themer->findNode( "user-entry" )) ||
+	     !(pw_entry = themer->findNode( "pw-entry" ))))
+		themer = 0;
+
+        m_themer = themer;
+
+	if (!themer)
+		layoutItem = new TQGridLayout( 0, 0, 10 );
+
+        loginLabel = 0;
+        authLabel.clear();
+        authEdit.clear();
+	loginLabel = 0;
+	loginEdit = 0;
+	if (ctx == ExUnlock || ctx == ExChangeTok)
+		fixedUser = KUser().loginName();
+	if (func != ChAuthTok) {
+		debug("func != ChAuthTok\n");
+		debug("fixedUser: *%s*\n", fixedUser.latin1());
+
+		if (fixedUser.isEmpty()) {
+			loginEdit = new KLineEdit( parent );
+			loginEdit->setContextMenuEnabled( false );
+			connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotLoginLostFocus()) );
+			connect( loginEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) );
+			connect( loginEdit, TQT_SIGNAL(textChanged( const TQString & )), TQT_SLOT(slotActivity()) );
+			connect( loginEdit, TQT_SIGNAL(selectionChanged()), TQT_SLOT(slotActivity()) );
+			if (pred) {
+				parent->setTabOrder( pred, loginEdit );
+				pred = loginEdit;
+			}
+			if (!getLayoutItem()) {
+				loginEdit->adjustSize();
+				user_entry->setWidget( loginEdit );
+			} else {
+				loginLabel = new TQLabel( loginEdit, i18n("Username:"), parent );
+				getLayoutItem()->addWidget( loginLabel, line, 0 );
+				getLayoutItem()->addWidget( loginEdit, line++, 1 );
+			}
+		} else if (ctx != Login && ctx != Shutdown && getLayoutItem()) {
+			loginLabel = new TQLabel( i18n("Username:"), parent );
+			getLayoutItem()->addWidget( loginLabel, line, 0 );
+			getLayoutItem()->addWidget( new TQLabel( fixedUser, parent ), line++, 1 );
+		}
+#if 0
+		if (echoMode == -1)
+			passwdEdit = new KDMPasswordEdit( parent );
+		else
+			passwdEdit = new KDMPasswordEdit( echoMode,
+			                                  parent );
+		connect( passwdEdit, TQT_SIGNAL(textChanged( const TQString & )),
+		         TQT_SLOT(slotActivity()) );
+		connect( passwdEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) );
+		if (pred) {
+			parent->setTabOrder( pred, passwdEdit );
+			pred = passwdEdit;
+		}
+		if (!getLayoutItem()) {
+			passwdEdit->adjustSize();
+			pw_entry->setWidget( passwdEdit );
+		} else {
+			passwdLabel = new TQLabel( passwdEdit,
+			                          func == Authenticate ?
+			                            i18n("hello &Password:") :
+			                            i18n("Current &password:"),
+			                          parent );
+			getLayoutItem()->addWidget( passwdLabel, line, 0 );
+			getLayoutItem()->addWidget( passwdEdit, line++, 1 );
+		}
+#endif
+		if (loginEdit)
+			loginEdit->setFocus();
+	}
+	if (func != Authenticate) {
+		if (echoMode == -1) {
+                        authEdit << new KDMPasswordEdit( echoMode, parent );
+			authEdit << new KDMPasswordEdit( echoMode, parent );
+		} else {
+			authEdit << new KDMPasswordEdit( parent );
+			authEdit << new KDMPasswordEdit( parent );
+		}
+		authLabel << new TQLabel( authEdit[0], i18n("&New password:"), parent );
+		authLabel << new TQLabel( authEdit[1], i18n("Con&firm password:"), parent );
+		if (pred) {
+			parent->setTabOrder( pred, authEdit[0] );
+			parent->setTabOrder( authEdit[0], authEdit[1] );
+		}
+		if (getLayoutItem()) {
+			getLayoutItem()->addWidget( authLabel[0], line, 0 );
+			getLayoutItem()->addWidget( authEdit[0], line++, 1 );
+			getLayoutItem()->addWidget( authLabel[1], line, 0 );
+			getLayoutItem()->addWidget( authEdit[1], line, 1 );
+		}
+		if (authEdit.size() >= 2)
+                        authEdit[1]->setFocus();
+	}
+}
+
+// virtual
+KPamGreeter::~KPamGreeter()
+{
+        debug("KPamGreeter::~KPamGreeter");
+	abort();
+	if (!layoutItem) {
+		delete loginEdit;
+		return;
+	}
+	TQLayoutIterator it = static_cast<TQLayout *>(layoutItem)->iterator();
+	for (TQLayoutItem *itm = it.current(); itm; itm = ++it)
+		 delete itm->widget();
+	delete layoutItem;
+        debug("destructor finished, good bye");
+}
+
+void // virtual
+KPamGreeter::loadUsers( const TQStringList &users )
+{
+	KCompletion *userNamesCompletion = new KCompletion;
+	userNamesCompletion->setItems( users );
+	loginEdit->setCompletionObject( userNamesCompletion );
+	loginEdit->setAutoDeleteCompletionObject( true );
+	loginEdit->setCompletionMode( KGlobalSettings::CompletionAuto );
+}
+
+void // virtual
+KPamGreeter::presetEntity( const TQString &entity, int field )
+{
+        debug("presetEntity(%s,%d) called!\n", entity.latin1(), field);
+	loginEdit->setText( entity );
+	if (field == 1 && authEdit.size() >= 1)
+		authEdit[0]->setFocus();
+	else {
+		loginEdit->setFocus();
+		loginEdit->selectAll();
+		if (field == -1 && authEdit.size() >= 1) {
+			authEdit[0]->setText( "     " );
+			authEdit[0]->setEnabled( false );
+			authTok = false;
+		}
+	}
+	curUser = entity;
+}
+
+TQString // virtual
+KPamGreeter::getEntity() const
+{
+	return fixedUser.isEmpty() ? loginEdit->text() : fixedUser;
+}
+
+void // virtual
+KPamGreeter::setUser( const TQString &user )
+{
+	// assert( fixedUser.isEmpty() );
+	curUser = user;
+	loginEdit->setText( user );
+        if (authEdit.size() >= 1) {
+	    authEdit[0]->setFocus();
+ 	    authEdit[0]->selectAll();
+        }
+}
+
+void // virtual
+KPamGreeter::setEnabled(bool enable)
+{
+	// assert( !passwd1Label );
+	// assert( func == Authenticate && ctx == Shutdown );
+//	if (loginLabel)
+//		loginLabel->setEnabled( enable );
+		authEdit[0]->setEnabled( enable );
+		setActive( enable );
+		if (enable)
+			authEdit[0]->setFocus();
+	}
+
+void // private
+KPamGreeter::returnData()
+{
+       debug("*************** returnData called with exp %d\n", exp);
+
+
+	switch (exp) {
+	case 0:
+		handler->gplugReturnText( (loginEdit ? loginEdit->text() :
+						       fixedUser).local8Bit(),
+					  KGreeterPluginHandler::IsUser );
+		break;
+	case 1:
+		handler->gplugReturnText( authEdit[0]->password(),
+					  KGreeterPluginHandler::IsPassword |
+					  KGreeterPluginHandler::IsSecret );
+		break;
+	case 2:
+		handler->gplugReturnText( authEdit[1]->password(),
+					  KGreeterPluginHandler::IsSecret );
+		break;
+	default: // case 3:
+		handler->gplugReturnText( authEdit[2]->password(),
+					  KGreeterPluginHandler::IsNewPassword |
+					  KGreeterPluginHandler::IsSecret );
+		break;
+	}
+}
+
+bool // virtual
+KPamGreeter::textMessage( const char *text, bool err )
+{
+    debug(" ************** textMessage(%s, %d)\n", text, err);
+
+    if (!authEdit.size())
+	    return false;
+
+    if (getLayoutItem()) {
+      TQLabel* label = new TQLabel(TQString::fromUtf8(text), m_parentWidget);
+      getLayoutItem()->addWidget(label, state+1, 0, 0);
+    }
+
+    return true;
+}
+
+void // virtual
+KPamGreeter::textPrompt( const char *prompt, bool echo, bool nonBlocking )
+{
+    debug("textPrompt called with prompt %s echo %d nonBlocking %d", prompt, echo, nonBlocking);
+    debug("state is %d, authEdit.size is %d\n", state, authEdit.size());
+
+    if (state == 0 && echo) {
+        if (loginLabel)
+	    loginLabel->setText(TQString::fromUtf8(prompt));
+        else if (m_themer) {
+            KdmLabel *kdmlabel = static_cast<KdmLabel*>(m_themer->findNode("user-label"));
+            if (kdmlabel) {
+                //userLabel->setText(TQString::fromUtf8(prompt));
+                kdmlabel->label.text = TQString::fromUtf8(prompt);
+                TQTimer::singleShot(0, kdmlabel, TQT_SLOT(update()));
+            }
+        }
+    }
+    else if (state >= authEdit.size()) {
+	if (getLayoutItem()) {
+   	    TQLabel* label = new TQLabel(TQString::fromUtf8(prompt), m_parentWidget);
+	    getLayoutItem()->addWidget(label, state+1, 0, 0);
+            debug("added label widget to layout");
+        }
+        else if (m_themer) {
+            debug("themer found!");
+	    KdmItem *pw_label = 0;
+
+            KdmLabel *kdmlabel = static_cast<KdmLabel*>(m_themer->findNode("pw-label"));
+            if (kdmlabel) {
+                //userLabel->setText(TQString::fromUtf8(prompt));
+                TQString str = TQString::fromUtf8(prompt);
+                kdmlabel->label.text = str;
+                TQTimer::singleShot(0, kdmlabel, TQT_SLOT(update()));
+            }
+        }
+
+	KDMPasswordEdit* passwdEdit;
+
+	if (echoMode == -1)
+	    passwdEdit = new KDMPasswordEdit( m_parentWidget );
+	else
+	    passwdEdit = new KDMPasswordEdit( echoMode, m_parentWidget);
+	connect( passwdEdit, TQT_SIGNAL(textChanged( const TQString & )),
+		TQT_SLOT(slotActivity()) );
+	connect( passwdEdit, TQT_SIGNAL(lostFocus()), TQT_SLOT(slotActivity()) );
+	authEdit << passwdEdit;
+
+#if 1
+       for(TQValueList<KPasswordEdit*>::iterator it = authEdit.begin();
+        it != authEdit.end();
+        ++it) {
+       if ((*it)->isEnabled() && (*it)->text().isEmpty()) {
+          (*it)->setFocus();
+          break;
+        }
+       }
+#endif
+       if (getLayoutItem())
+	   getLayoutItem()->addWidget(passwdEdit, state+1, 1, 0);
+
+       if (m_themer) {
+           debug("themer found!");
+	   KdmItem *pw_entry = 0;
+
+	   pw_entry = m_themer->findNode("pw-entry");
+
+	   if (pw_entry && passwdEdit)
+	       pw_entry->setWidget(passwdEdit);
+
+           if (0) {
+                //userLabel->setText(TQString::fromUtf8(prompt));
+                //kdmlabel->label.text = TQString::fromUtf8(prompt);
+                //TQTimer::singleShot(0, kdmlabel, TQT_SLOT(update()));
+           }
+       } 
+       else
+           debug("no themer found!");
+    }
+    ++state;
+    pExp = exp;
+
+    exp = authEdit.size();
+    debug("state %d exp: %d, has %d\n", state, exp, has);
+
+    if (has >= exp || nonBlocking)
+	returnData();
+}
+
+bool // virtual
+KPamGreeter::binaryPrompt( const char *, bool )
+{
+	// this simply cannot happen ... :}
+	return true;
+}
+
+void // virtual
+KPamGreeter::start()
+{
+   debug("******* start() called\n");
+
+   while(authEdit.begin() != authEdit.end()) {
+       KPasswordEdit* item = *authEdit.remove(authEdit.begin());
+       delete item;
+   }
+
+   while(authLabel.begin() != authLabel.end()) {
+       TQLabel* item = *authLabel.remove(authLabel.begin());
+       delete item;
+   }
+
+   authTok = !(authEdit.size() >= 2 && authEdit[1]->isEnabled());
+   exp = has = -1;
+   state = 0;
+   running = true;
+   handler->gplugStart();
+}
+
+void // virtual
+KPamGreeter::suspend()
+{
+}
+
+void // virtual
+KPamGreeter::resume()
+{
+}
+
+void // virtual
+KPamGreeter::next()
+{
+        debug("********* next() called state %d\n", state);
+
+	if (state == 0 && running && handler) {
+                debug(" **** returned text!\n");
+		handler->gplugReturnText( (loginEdit ? loginEdit->text() :
+		                  fixedUser).local8Bit(),
+		                          KGreeterPluginHandler::IsUser );
+                setActive(false);
+        }
+	
+        has = 0;
+
+    for(TQValueList<KPasswordEdit*>::iterator it = authEdit.begin();
+        it != authEdit.end();
+        ++it) {
+
+          has++;
+        if ((*it)->hasFocus()) {
+          ++it;
+          if (it != authEdit.end())
+              (*it)->setFocus();
+          break;
+        }
+        if (it == authEdit.end())
+           has = -1;
+   }
+
+   debug(" has %d and exp %d\n", has, exp);
+
+#if 0
+	// assert( running );
+	if (loginEdit && loginEdit->hasFocus()) {
+		passwdEdit->setFocus(); // will cancel running login if necessary
+		has = 0;
+	} else if (passwdEdit && passwdEdit->hasFocus()) {
+		if (passwd1Edit)
+			passwd1Edit->setFocus();
+		has = 1;
+	} else if (passwd1Edit) {
+		if (passwd1Edit->hasFocus()) {
+			passwd2Edit->setFocus();
+			has = 1; // sic!
+		} else
+			has = 3;
+	} else
+		has = 1;
+	if (exp < 0)
+		handler->gplugStart();
+#endif
+	if (has >= exp)
+		returnData();
+}
+
+void // virtual
+KPamGreeter::abort()
+{
+	debug("***** abort() called\n");
+
+	running = false;
+	if (exp >= 0) {
+		exp = -1;
+		handler->gplugReturnText( 0, 0 );
+	}
+}
+
+void // virtual
+KPamGreeter::succeeded()
+{
+        debug("**** succeeded() called\n");
+
+	// assert( running || timed_login );
+	if (!authTok)
+		setActive( false );
+	else
+		setAllActive( false );
+	exp = -1;
+	running = false;
+}
+
+void // virtual
+KPamGreeter::failed()
+{
+	// assert( running || timed_login );
+	setActive( false );
+	setAllActive( false );
+	exp = -1;
+	running = false;
+}
+
+#include<assert.h>
+void // virtual
+KPamGreeter::revive()
+{
+	// assert( !running );
+	setAllActive( true );
+
+#if 1
+        if (authEdit.size()  < 1)
+                return;
+#endif
+
+        assert(authEdit.size() >= 1);
+	if (authTok) {
+		authEdit[0]->erase();
+                if(authEdit.size() >= 2)
+			authEdit[1]->erase();
+		authEdit[0]->setFocus();
+	} else {
+		authEdit[0]->erase();
+		if (loginEdit && loginEdit->isEnabled())
+			authEdit[0]->setEnabled( true );
+		else {
+			setActive( true );
+			if (loginEdit && loginEdit->text().isEmpty())
+				loginEdit->setFocus();
+			else
+				authEdit[0]->setFocus();
+		}
+	}
+}
+
+void // virtual
+KPamGreeter::clear()
+{
+	// assert( !running && !passwd1Edit );
+	authEdit[0]->erase();
+	if (loginEdit) {
+		loginEdit->clear();
+		loginEdit->setFocus();
+		curUser = TQString::null;
+	} else
+		authEdit[0]->setFocus();
+}
+
+
+// private
+
+void
+KPamGreeter::setActive( bool enable )
+{
+	if (loginEdit)
+		loginEdit->setEnabled( enable );
+}
+
+void
+KPamGreeter::setAllActive( bool enable )
+{
+    for(TQValueList<KPasswordEdit*>::iterator it = authEdit.begin();
+        it != authEdit.end();
+        ++it)
+        (*it)->setEnabled( enable );
+}
+
+void
+KPamGreeter::slotLoginLostFocus()
+{
+	if (!running)
+		return;
+	if (exp > 0) {
+		if (curUser == loginEdit->text())
+			return;
+		exp = -1;
+		handler->gplugReturnText( 0, 0 );
+	}
+	curUser = loginEdit->text();
+        debug("curUser is %s", curUser.latin1());
+	handler->gplugSetUser( curUser );
+}
+
+void
+KPamGreeter::slotActivity()
+{  
+        debug("slotActivity");
+
+	if (running)
+		handler->gplugActivity();
+}
+
+// factory
+
+static bool init( const TQString &,
+                  TQVariant (*getConf)( void *, const char *, const TQVariant & ),
+                  void *ctx )
+{
+	echoMode = (KPasswordEdit::EchoModes) getConf( ctx, "EchoMode", TQVariant( -1 ) ).toInt();
+	KGlobal::locale()->insertCatalogue( "kgreet_pam" );
+	return true;
+}
+
+static void done( void )
+{
+	KGlobal::locale()->removeCatalogue( "kgreet_pam" );
+        if (log && log != stderr)
+	    fclose(log);
+        log = 0;
+}
+
+static KGreeterPlugin *
+create( KGreeterPluginHandler *handler, KdmThemer *themer,
+        TQWidget *parent, TQWidget *predecessor,
+        const TQString &fixedEntity,
+        KGreeterPlugin::Function func,
+        KGreeterPlugin::Context ctx )
+{
+	return new KPamGreeter( handler, themer, parent, predecessor, fixedEntity, func, ctx );
+}
+
+KDE_EXPORT kgreeterplugin_info kgreeterplugin_info = {
+	I18N_NOOP("Pam conversation plugin"), "pam",
+	kgreeterplugin_info::Local | kgreeterplugin_info::Presettable,
+	init, done, create
+};
+
+#include "kgreet_pam.moc"
diff --git a/kdmlib/kgreet_pam.h b/kdmlib/kgreet_pam.h
new file mode 100644
index 000000000..f0bea7d02
--- /dev/null
+++ b/kdmlib/kgreet_pam.h
@@ -0,0 +1,93 @@
+/*
+
+Conversation widget for kdm greeter
+
+Copyright (C) 2008 Dirk Mueller <mueller@kde.org>
+
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+*/
+
+
+#ifndef KGREET_CLASSIC_H
+#define KGREET_CLASSIC_H
+
+#include "kgreeterplugin.h"
+
+#include <tqobject.h>
+#include <tqlayout.h>
+
+class KLineEdit;
+class KPasswordEdit;
+class KSimpleConfig;
+class TQGridLayout;
+class TQLabel;
+
+class KPamGreeter : public TQObject, public KGreeterPlugin {
+	Q_OBJECT
+
+  public:
+	KPamGreeter( KGreeterPluginHandler *handler,
+	                 KdmThemer *themer,
+	                 TQWidget *parent, TQWidget *predecessor,
+	                 const TQString &fixedEntitiy,
+	                 Function func, Context ctx );
+	~KPamGreeter();
+	virtual void loadUsers( const TQStringList &users );
+	virtual void presetEntity( const TQString &entity, int field );
+	virtual TQString getEntity() const;
+	virtual void setUser( const TQString &user );
+	virtual void setEnabled( bool on );
+	virtual bool textMessage( const char *message, bool error );
+	virtual void textPrompt( const char *prompt, bool echo, bool nonBlocking );
+	virtual bool binaryPrompt( const char *prompt, bool nonBlocking );
+	virtual void start();
+	virtual void suspend();
+	virtual void resume();
+	virtual void next();
+	virtual void abort();
+	virtual void succeeded();
+	virtual void failed();
+	virtual void revive();
+	virtual void clear();
+
+        TQGridLayout *getLayoutItem() const { return static_cast<TQGridLayout*>(layoutItem); }
+
+  public slots:
+	void slotLoginLostFocus();
+	void slotActivity();
+
+  private:
+	void setActive( bool enable );
+	void setAllActive( bool enable );
+	void returnData();
+
+        TQLabel *loginLabel;
+        TQValueList<TQLabel*> authLabel;
+	KLineEdit *loginEdit;
+        TQWidget* m_parentWidget;
+        TQValueList<KPasswordEdit*> authEdit;
+	KSimpleConfig *stsFile;
+        KdmThemer *m_themer;
+	TQString fixedUser, curUser;
+	Function func;
+	Context ctx;
+	int exp, pExp, has;
+        unsigned state;
+	bool running, authTok;
+};
+
+#endif /* KGREET_CLASSIC_H */
diff --git a/khelpcenter/kcmhelpcenter.cpp b/khelpcenter/kcmhelpcenter.cpp
index c3b3e3094..aadce700a 100644
--- a/khelpcenter/kcmhelpcenter.cpp
+++ b/khelpcenter/kcmhelpcenter.cpp
@@ -321,6 +321,7 @@ bool KCMHelpCenter::save()
 
 void KCMHelpCenter::load()
 {
+  findWriteableIndexDir();
   mIndexDirLabel->setText( Prefs::indexDirectory() );
 
   mListView->clear();
@@ -675,6 +676,12 @@ void KCMHelpCenter::checkSelection()
   enableButtonOK( count != 0 );
 }
 
+void KCMHelpCenter::findWriteableIndexDir()
+{
+  TQFileInfo currentDir( Prefs::indexDirectory() );
+  if ( !currentDir.isWritable() )
+    Prefs::setIndexDirectory( KGlobal::dirs()->saveLocation("data", "khelpcenter/index/") );
+}
 #include "kcmhelpcenter.moc"
 
 // vim:ts=2:sw=2:et
diff --git a/khelpcenter/kcmhelpcenter.h b/khelpcenter/kcmhelpcenter.h
index 4715d1a0a..8bf2f3b6c 100644
--- a/khelpcenter/kcmhelpcenter.h
+++ b/khelpcenter/kcmhelpcenter.h
@@ -146,6 +146,11 @@ class KCMHelpCenter : public KDialogBase, virtual public KCMHelpCenterIface
 
     void advanceProgress();
 
+    /**
+     * Find a user-writeable location for the indices, if the current location
+     * is not.
+     */
+    void findWriteableIndexDir();
   private:
     KHC::SearchEngine *mEngine;
   
diff --git a/khelpcenter/navigator.cpp b/khelpcenter/navigator.cpp
index 48ae76dd0..ad308cfc6 100644
--- a/khelpcenter/navigator.cpp
+++ b/khelpcenter/navigator.cpp
@@ -120,8 +120,6 @@ Navigator::Navigator( View *view, TQWidget *parent, const char *name )
 
     mTabWidget = new TQTabWidget( this );
     topLayout->addWidget( mTabWidget );
-    connect( mTabWidget, TQT_SIGNAL( currentChanged( TQWidget * ) ),
-             TQT_SLOT( slotTabChanged( TQWidget * ) ) );
 
     setupContentsTab();
     setupGlossaryTab();
@@ -135,6 +133,9 @@ Navigator::Navigator( View *view, TQWidget *parent, const char *name )
       mSearchWidget->updateScopeList();
       mSearchWidget->readConfig( KGlobal::config() );
     }
+
+    connect( mTabWidget, TQT_SIGNAL( currentChanged( QWidget * ) ),
+             TQT_SLOT( slotTabChanged( QWidget * ) ) );
 }
 
 Navigator::~Navigator()
@@ -336,6 +337,11 @@ void Navigator::selectItem( const KURL &url )
           item = item->nextSibling() ) {
       NavigatorAppItem *appItem = dynamic_cast<NavigatorAppItem *>( item );
       if ( appItem ) appItem->populate( true /* recursive */ );
+      for ( QListViewItem *subitem = item->firstChild(); subitem;
+	    subitem = subitem->nextSibling() ) {
+	appItem = dynamic_cast<NavigatorAppItem *>( subitem );
+	if ( appItem ) appItem->populate( true /* recursive */ );
+      }
     }
   }
 
diff --git a/khelpcenter/searchhandlers/Makefile.am b/khelpcenter/searchhandlers/Makefile.am
index 65f4060b6..f2ebd57ff 100644
--- a/khelpcenter/searchhandlers/Makefile.am
+++ b/khelpcenter/searchhandlers/Makefile.am
@@ -3,7 +3,7 @@ searchhandlers_DATA = htdig.desktop man.desktop docbook.desktop
 searchhandlersdir = $(kde_datadir)/khelpcenter/searchhandlers
 
 kde_bin_SCRIPTS = khc_htdig.pl khc_htsearch.pl khc_mansearch.pl \
-  khc_docbookdig.pl
+  khc_docbookdig.pl khc_beagle_search.pl khc_beagle_index.pl
 
 htdigdata_DATA = htdig_long.html
 
diff --git a/khelpcenter/searchhandlers/docbook.desktop b/khelpcenter/searchhandlers/docbook.desktop
index 08208c187..5c6d11284 100644
--- a/khelpcenter/searchhandlers/docbook.desktop
+++ b/khelpcenter/searchhandlers/docbook.desktop
@@ -2,5 +2,5 @@
 
 DocumentTypes=text/docbook
 
-SearchCommand=khc_htsearch.pl --docbook --indexdir=%d --config=%i --words=%w --method=%o --maxnum=%m --lang=en
-IndexCommand=khc_docbookdig.pl --indexdir=%d --docpath=%p --identifier=%i
+SearchCommand=khc_beagle_search.pl --method=%o --maxnum=%m %w
+IndexCommand=khc_beagle_index.pl %d %i
diff --git a/khelpcenter/searchhandlers/khc_beagle_index.pl b/khelpcenter/searchhandlers/khc_beagle_index.pl
new file mode 100644
index 000000000..02f1b9330
--- /dev/null
+++ b/khelpcenter/searchhandlers/khc_beagle_index.pl
@@ -0,0 +1,49 @@
+#!/usr/bin/perl
+# vim:sw=4:et
+
+use warnings;
+
+sub getKDEDocDir() 
+{
+    my $prefix = `kde-config --prefix`;
+    chomp $prefix;
+
+    $prefix = "/opt/kde" if (not defined($prefix));
+    return "$prefix/share/doc";
+}
+
+sub addRoot() 
+{
+    my $kdedocdir = &getKDEDocDir;
+
+    open (IN, "-|") || exec "beagle-config", "indexing", "ListRoots";
+
+    my $kdedoc_found = 0;
+    while(<IN>) {
+        if (/^$kdedocdir/o) {
+            $kdedoc_found = 1;
+            last;
+        }
+    }
+    close(IN);
+
+    if (not $kdedoc_found) {
+        `beagle-config indexing AddRoot $kdedocdir`;
+        `beagle-config indexing AddRoot $kdedocdir-bundle`;
+    }
+}
+
+sub createExistsFile($$)
+{
+    my ($idir, $ident) = @_;
+
+    open(OUT, ">", "$idir/$idir");
+    close(OUT);
+}
+
+my $idir = $ARGV[0];
+my $ident = $ARGV[1];
+
+if (addRoot) {
+    createExistsFile($idir, $ident);
+}
diff --git a/khelpcenter/searchhandlers/khc_beagle_search.pl b/khelpcenter/searchhandlers/khc_beagle_search.pl
new file mode 100644
index 000000000..d7a1f44b8
--- /dev/null
+++ b/khelpcenter/searchhandlers/khc_beagle_search.pl
@@ -0,0 +1,88 @@
+#!/usr/bin/perl -w
+# vim:sw=4:et
+
+use warnings;
+use strict;
+use Getopt::Long;
+
+sub isBeagleRunning()
+{
+    open(IN, "-|") || exec "beagle-ping";
+    while(<IN>) {
+        if (/^Daemon version:/) {
+            close(IN);
+            return 1;
+        }
+    }
+    close(IN);
+    return 0;
+}
+
+sub formatHTML($$)
+{
+    my ($query, $hits) = @_;
+
+    print "<html>\n<body\n<ul>\n";
+
+    foreach my $hit(@$hits) {
+        print "<li>$hit</li>\n";
+    }
+    print "</ul>\n</body>\n</html>\n";
+}
+
+sub beagleQuery($$$)
+{
+    my ($words, $method, $maxnum) = @_;
+
+    my @hits = ();
+
+    open(IN, "-|") || exec "beagle-query", "--type", "DocbookEntry", "--type", "File", "--max-hits", $maxnum, @$words, "ext:docbook";
+    while(<IN>) {
+        chop;
+        next if (/^Debug:/);
+
+        my $uri = $_;
+        $uri = $1 if ($uri =~ /^file:\/\/(.*)$/);
+
+        print "uri: $uri\n";
+        my $helpLink = &makeHelpLink($uri);
+
+        push(@hits, $helpLink) if (!grep { /^$helpLink$/ } @hits);
+    }
+    close(IN);
+    return @hits;
+}
+
+sub makeHelpLink($)
+{
+    # Try to figure out the name of the application from the path to its index.docbook file
+
+    my ($path) = @_;
+    my @pathcomponents = split '/', $path;
+
+    my $appName = $pathcomponents[-2];
+    my $appName2 = $pathcomponents[-3];
+
+    if ($appName eq $appName2 or $appName2 eq "doc" 
+        or (-d "/usr/share/locale/$appName2")) {
+        return "<a href=\"help:/$appName\">$appName</a>";
+    }
+    return "<a href=\"help:/$appName2/$appName\">$appName ($appName2)</a>";
+}
+
+my $method = "and";
+my $maxnum = 100;
+
+GetOptions("method=s", \$method, "maxnum=i", \$maxnum);
+
+my @hits = ("The Beagle daemon is not running, search is not available");
+
+my @words = @ARGV;
+
+if (isBeagleRunning()) {
+    @hits = beagleQuery(\@words, $method, $maxnum);
+}
+
+@hits = ("There are no search results") if ($#hits < 0);
+
+formatHTML(\@words, \@hits);
diff --git a/kicker/applets/systemtray/systemtrayapplet.cpp b/kicker/applets/systemtray/systemtrayapplet.cpp
index 933855f74..51bf2b9d8 100644
--- a/kicker/applets/systemtray/systemtrayapplet.cpp
+++ b/kicker/applets/systemtray/systemtrayapplet.cpp
@@ -189,6 +189,7 @@ bool SystemTrayApplet::x11Event( XEvent *e )
             if( isWinManaged( (WId)e->xclient.data.l[2] ) ) // we already manage it
                 return true;
             embedWindow( e->xclient.data.l[2], false );
+            updateVisibleWins();
             layoutTray();
             return true;
         }
@@ -215,13 +216,12 @@ void SystemTrayApplet::preferences()
     connect(m_settingsDialog, TQT_SIGNAL(finished()), this, TQT_SLOT(settingsDialogFinished()));
 
     m_iconSelector = new KActionSelector(m_settingsDialog);
-    m_iconSelector->setAvailableLabel(i18n("Visible icons:"));
-    m_iconSelector->setSelectedLabel(i18n("Hidden icons:"));
-    m_iconSelector->setShowUpDownButtons(false);
+    m_iconSelector->setAvailableLabel(i18n("Hidden icons:"));
+    m_iconSelector->setSelectedLabel(i18n("Visible icons:"));
     m_settingsDialog->setMainWidget(m_iconSelector);
 
-    TQListBox *shownListBox = m_iconSelector->availableListBox();
-    TQListBox *hiddenListBox = m_iconSelector->selectedListBox();
+    TQListBox *hiddenListBox = m_iconSelector->availableListBox();
+    TQListBox *shownListBox = m_iconSelector->selectedListBox();
 
     TrayEmbedList::const_iterator it = m_shownWins.begin();
     TrayEmbedList::const_iterator itEnd = m_shownWins.end();
@@ -263,26 +263,48 @@ void SystemTrayApplet::applySettings()
     }
 
     KConfig *conf = config();
-    conf->setGroup("HiddenTrayIcons");
-    TQString name;
-
-    // use the following snippet of code someday to implement ordering
-    // of icons
-    /*
-    m_visibleIconList.clear();
-    TQListBoxItem* item = m_iconSelector->availableListBox()->firstItem();
-    for (; item; item = item->next())
+
+    // Save the sort order and hidden status using the window class (WM_CLASS) rather
+    // than window name (caption) - window name is i18n-ed, so it's for example
+    // not possible to create default settings.
+    // For backwards compatibility, name is kept as it is, class is preceded by '!'.
+    TQMap< TQString, TQString > windowNameToClass;
+    for( TrayEmbedList::ConstIterator it = m_shownWins.begin();
+         it != m_shownWins.end();
+         ++it ) {
+        KWin::WindowInfo info = KWin::windowInfo( (*it)->embeddedWinId(), NET::WMName, NET::WM2WindowClass);
+        windowNameToClass[ info.name() ] = '!' + info.windowClassClass();
+    }
+    for( TrayEmbedList::ConstIterator it = m_hiddenWins.begin();
+         it != m_hiddenWins.end();
+         ++it ) {
+        KWin::WindowInfo info = KWin::windowInfo( (*it)->embeddedWinId(), NET::WMName, NET::WM2WindowClass);
+        windowNameToClass[ info.name() ] = '!' + info.windowClassClass();
+    }
+
+    conf->setGroup("SortedTrayIcons");
+    m_sortOrderIconList.clear();
+    for(TQListBoxItem* item = m_iconSelector->selectedListBox()->firstItem();
+        item;
+        item = item->next())
     {
-        m_visibleIconList.append(item->text());
+        if( windowNameToClass.contains(item->text()))
+            m_sortOrderIconList.append(windowNameToClass[item->text()]);
+        else
+            m_sortOrderIconList.append(item->text());
     }
-    conf->writeEntry("Visible", m_visibleIconList);
-    selection.clear();*/
+    conf->writeEntry("SortOrder", m_sortOrderIconList);
 
+    conf->setGroup("HiddenTrayIcons");
     m_hiddenIconList.clear();
-    TQListBoxItem* item = m_iconSelector->selectedListBox()->firstItem();
-    for (; item; item = item->next())
+    for(TQListBoxItem* item = m_iconSelector->availableListBox()->firstItem();
+        item;
+        item = item->next())
     {
-        m_hiddenIconList.append(item->text());
+        if( windowNameToClass.contains(item->text()))
+            m_hiddenIconList.append(windowNameToClass[item->text()]);
+        else
+            m_hiddenIconList.append(item->text());
     }
     conf->writeEntry("Hidden", m_hiddenIconList);
     conf->sync();
@@ -437,6 +459,9 @@ void SystemTrayApplet::loadSettings()
     conf->setGroup("HiddenTrayIcons");
     m_hiddenIconList = conf->readListEntry("Hidden");
 
+    conf->setGroup("SortedTrayIcons");
+    m_sortOrderIconList = conf->readListEntry("SortOrder");
+
     //Note This setting comes from kdeglobal.
     conf->setGroup("System Tray");
     m_iconSize = conf->readNumEntry("systrayIconWidth", 22);
@@ -526,7 +551,9 @@ bool SystemTrayApplet::isWinManaged(WId w)
 
 bool SystemTrayApplet::shouldHide(WId w)
 {
-    return m_hiddenIconList.find(KWin::windowInfo(w).name()) != m_hiddenIconList.end();
+    return m_hiddenIconList.find(KWin::windowInfo(w).name()) != m_hiddenIconList.end()
+        || m_hiddenIconList.find('!'+KWin::windowInfo(w,0,NET::WM2WindowClass).windowClassClass())
+            != m_hiddenIconList.end();
 }
 
 void SystemTrayApplet::updateVisibleWins()
@@ -549,6 +576,35 @@ void SystemTrayApplet::updateVisibleWins()
             (*emb)->hide();
         }
     }
+    
+    TQMap< QXEmbed*, TQString > names; // cache window names and classes
+    TQMap< QXEmbed*, TQString > classes;
+    for( TrayEmbedList::const_iterator it = m_shownWins.begin();
+         it != m_shownWins.end();
+         ++it ) {
+        KWin::WindowInfo info = KWin::windowInfo((*it)->embeddedWinId(),NET::WMName,NET::WM2WindowClass);
+        names[ *it ] = info.name();
+        classes[ *it ] = '!'+info.windowClassClass();
+    }
+    TrayEmbedList newList;
+    for( TQStringList::const_iterator it1 = m_sortOrderIconList.begin();
+         it1 != m_sortOrderIconList.end();
+         ++it1 ) {
+        for( TrayEmbedList::iterator it2 = m_shownWins.begin();
+             it2 != m_shownWins.end();
+             ) {
+            if( (*it1).startsWith("!") ? classes[ *it2 ] == *it1 : names[ *it2 ] == *it1 ) {
+                newList.append( *it2 ); // don't bail out, there may be multiple ones
+                it2 = m_shownWins.erase( it2 );
+            } else
+                ++it2;
+        }
+    }
+    for( TrayEmbedList::const_iterator it = m_shownWins.begin();
+         it != m_shownWins.end();
+         ++it )
+        newList.append( *it ); // append unsorted items
+    m_shownWins = newList;
 }
 
 void SystemTrayApplet::toggleExpanded()
diff --git a/kicker/applets/systemtray/systemtrayapplet.h b/kicker/applets/systemtray/systemtrayapplet.h
index a92b8f74e..f66e0caa5 100644
--- a/kicker/applets/systemtray/systemtrayapplet.h
+++ b/kicker/applets/systemtray/systemtrayapplet.h
@@ -98,6 +98,7 @@ private:
     TrayEmbedList m_shownWins;
     TrayEmbedList m_hiddenWins;
     TQStringList m_hiddenIconList;
+    TQStringList m_sortOrderIconList;
     KWinModule *kwin_module;
     Atom net_system_tray_selection;
     Atom net_system_tray_opcode;
diff --git a/kicker/data/kickoff/button-box-gradient-topdown.png b/kicker/data/kickoff/button-box-gradient-topdown.png
new file mode 100644
index 000000000..378816342
Binary files /dev/null and b/kicker/data/kickoff/button-box-gradient-topdown.png differ
diff --git a/kicker/data/kickoff/button-box-gradient.png b/kicker/data/kickoff/button-box-gradient.png
new file mode 100644
index 000000000..a7c11adba
Binary files /dev/null and b/kicker/data/kickoff/button-box-gradient.png differ
diff --git a/kicker/data/kickoff/button-box-left-corner.png b/kicker/data/kickoff/button-box-left-corner.png
new file mode 100644
index 000000000..c4080cb00
Binary files /dev/null and b/kicker/data/kickoff/button-box-left-corner.png differ
diff --git a/kicker/data/kickoff/button-box-left.png b/kicker/data/kickoff/button-box-left.png
new file mode 100644
index 000000000..3b532f8bd
Binary files /dev/null and b/kicker/data/kickoff/button-box-left.png differ
diff --git a/kicker/data/kickoff/button-box-right-corner.png b/kicker/data/kickoff/button-box-right-corner.png
new file mode 100644
index 000000000..ef44b1fab
Binary files /dev/null and b/kicker/data/kickoff/button-box-right-corner.png differ
diff --git a/kicker/data/kickoff/button-box-top.png b/kicker/data/kickoff/button-box-top.png
new file mode 100644
index 000000000..1cac298be
Binary files /dev/null and b/kicker/data/kickoff/button-box-top.png differ
diff --git a/kicker/data/kickoff/cr128-action-suspend2disk.png b/kicker/data/kickoff/cr128-action-suspend2disk.png
new file mode 100644
index 000000000..b3ac2fe05
Binary files /dev/null and b/kicker/data/kickoff/cr128-action-suspend2disk.png differ
diff --git a/kicker/data/kickoff/cr128-action-suspend2ram.png b/kicker/data/kickoff/cr128-action-suspend2ram.png
new file mode 100644
index 000000000..9e641bd47
Binary files /dev/null and b/kicker/data/kickoff/cr128-action-suspend2ram.png differ
diff --git a/kicker/data/kickoff/cr16-action-suspend2disk.png b/kicker/data/kickoff/cr16-action-suspend2disk.png
new file mode 100644
index 000000000..a28ab8ad9
Binary files /dev/null and b/kicker/data/kickoff/cr16-action-suspend2disk.png differ
diff --git a/kicker/data/kickoff/cr16-action-suspend2ram.png b/kicker/data/kickoff/cr16-action-suspend2ram.png
new file mode 100644
index 000000000..45738ccc5
Binary files /dev/null and b/kicker/data/kickoff/cr16-action-suspend2ram.png differ
diff --git a/kicker/data/kickoff/cr32-action-leave.png b/kicker/data/kickoff/cr32-action-leave.png
new file mode 100644
index 000000000..89dc15953
Binary files /dev/null and b/kicker/data/kickoff/cr32-action-leave.png differ
diff --git a/kicker/data/kickoff/cr32-action-suspend2disk.png b/kicker/data/kickoff/cr32-action-suspend2disk.png
new file mode 100644
index 000000000..7bcb027b1
Binary files /dev/null and b/kicker/data/kickoff/cr32-action-suspend2disk.png differ
diff --git a/kicker/data/kickoff/cr32-action-suspend2ram.png b/kicker/data/kickoff/cr32-action-suspend2ram.png
new file mode 100644
index 000000000..7a96cd24f
Binary files /dev/null and b/kicker/data/kickoff/cr32-action-suspend2ram.png differ
diff --git a/kicker/data/kickoff/cr48-action-leave.png b/kicker/data/kickoff/cr48-action-leave.png
new file mode 100644
index 000000000..7c01634b9
Binary files /dev/null and b/kicker/data/kickoff/cr48-action-leave.png differ
diff --git a/kicker/data/kickoff/cr48-action-suspend2disk.png b/kicker/data/kickoff/cr48-action-suspend2disk.png
new file mode 100644
index 000000000..9ff2148b8
Binary files /dev/null and b/kicker/data/kickoff/cr48-action-suspend2disk.png differ
diff --git a/kicker/data/kickoff/cr48-action-suspend2ram.png b/kicker/data/kickoff/cr48-action-suspend2ram.png
new file mode 100644
index 000000000..2aefa6ce4
Binary files /dev/null and b/kicker/data/kickoff/cr48-action-suspend2ram.png differ
diff --git a/kicker/data/kickoff/cr48-app-recently_used.png b/kicker/data/kickoff/cr48-app-recently_used.png
new file mode 100644
index 000000000..b97479759
Binary files /dev/null and b/kicker/data/kickoff/cr48-app-recently_used.png differ
diff --git a/kicker/data/kickoff/cr64-action-suspend2disk.png b/kicker/data/kickoff/cr64-action-suspend2disk.png
new file mode 100644
index 000000000..f6e57d786
Binary files /dev/null and b/kicker/data/kickoff/cr64-action-suspend2disk.png differ
diff --git a/kicker/data/kickoff/cr64-action-suspend2ram.png b/kicker/data/kickoff/cr64-action-suspend2ram.png
new file mode 100644
index 000000000..cdb47d04f
Binary files /dev/null and b/kicker/data/kickoff/cr64-action-suspend2ram.png differ
diff --git a/kicker/data/kickoff/crsc-action-leave.svgz b/kicker/data/kickoff/crsc-action-leave.svgz
new file mode 100644
index 000000000..b6a93b05c
Binary files /dev/null and b/kicker/data/kickoff/crsc-action-leave.svgz differ
diff --git a/kicker/data/kickoff/crsc-action-suspend2disk.svgz b/kicker/data/kickoff/crsc-action-suspend2disk.svgz
new file mode 100644
index 000000000..d73b491d9
Binary files /dev/null and b/kicker/data/kickoff/crsc-action-suspend2disk.svgz differ
diff --git a/kicker/data/kickoff/crsc-action-suspend2ram.svgz b/kicker/data/kickoff/crsc-action-suspend2ram.svgz
new file mode 100644
index 000000000..c38d2ed33
Binary files /dev/null and b/kicker/data/kickoff/crsc-action-suspend2ram.svgz differ
diff --git a/kicker/data/kickoff/kmenu_active.png b/kicker/data/kickoff/kmenu_active.png
new file mode 100644
index 000000000..fa5ae4de1
Binary files /dev/null and b/kicker/data/kickoff/kmenu_active.png differ
diff --git a/kicker/data/kickoff/kmenu_basic.mng b/kicker/data/kickoff/kmenu_basic.mng
new file mode 100644
index 000000000..4cea61fff
Binary files /dev/null and b/kicker/data/kickoff/kmenu_basic.mng differ
diff --git a/kicker/data/kickoff/kmenu_flipped.mng b/kicker/data/kickoff/kmenu_flipped.mng
new file mode 100644
index 000000000..2b78b4007
Binary files /dev/null and b/kicker/data/kickoff/kmenu_flipped.mng differ
diff --git a/kicker/data/kickoff/kmenu_vertical.mng b/kicker/data/kickoff/kmenu_vertical.mng
new file mode 100644
index 000000000..9cd3aac2b
Binary files /dev/null and b/kicker/data/kickoff/kmenu_vertical.mng differ
diff --git a/kicker/data/kickoff/left_triangle.png b/kicker/data/kickoff/left_triangle.png
new file mode 100644
index 000000000..b8ac404fd
Binary files /dev/null and b/kicker/data/kickoff/left_triangle.png differ
diff --git a/kicker/data/kickoff/main_border_bc.png b/kicker/data/kickoff/main_border_bc.png
new file mode 100644
index 000000000..05e497763
Binary files /dev/null and b/kicker/data/kickoff/main_border_bc.png differ
diff --git a/kicker/data/kickoff/main_border_lc.png b/kicker/data/kickoff/main_border_lc.png
new file mode 100644
index 000000000..c440e859e
Binary files /dev/null and b/kicker/data/kickoff/main_border_lc.png differ
diff --git a/kicker/data/kickoff/main_border_rc.png b/kicker/data/kickoff/main_border_rc.png
new file mode 100644
index 000000000..6cef8af01
Binary files /dev/null and b/kicker/data/kickoff/main_border_rc.png differ
diff --git a/kicker/data/kickoff/main_border_tc.png b/kicker/data/kickoff/main_border_tc.png
new file mode 100644
index 000000000..bc03e85dd
Binary files /dev/null and b/kicker/data/kickoff/main_border_tc.png differ
diff --git a/kicker/data/kickoff/main_corner_bl.png b/kicker/data/kickoff/main_corner_bl.png
new file mode 100644
index 000000000..32ea680f1
Binary files /dev/null and b/kicker/data/kickoff/main_corner_bl.png differ
diff --git a/kicker/data/kickoff/main_corner_br.png b/kicker/data/kickoff/main_corner_br.png
new file mode 100644
index 000000000..b2d898ab6
Binary files /dev/null and b/kicker/data/kickoff/main_corner_br.png differ
diff --git a/kicker/data/kickoff/main_corner_tl.png b/kicker/data/kickoff/main_corner_tl.png
new file mode 100644
index 000000000..11fe645ce
Binary files /dev/null and b/kicker/data/kickoff/main_corner_tl.png differ
diff --git a/kicker/data/kickoff/main_corner_tr.png b/kicker/data/kickoff/main_corner_tr.png
new file mode 100644
index 000000000..a439d9763
Binary files /dev/null and b/kicker/data/kickoff/main_corner_tr.png differ
diff --git a/kicker/data/kickoff/menu_separator.png b/kicker/data/kickoff/menu_separator.png
new file mode 100644
index 000000000..2ba13727d
Binary files /dev/null and b/kicker/data/kickoff/menu_separator.png differ
diff --git a/kicker/data/kickoff/resize_handle.png b/kicker/data/kickoff/resize_handle.png
new file mode 100644
index 000000000..c0811dc50
Binary files /dev/null and b/kicker/data/kickoff/resize_handle.png differ
diff --git a/kicker/data/kickoff/right_triangle.png b/kicker/data/kickoff/right_triangle.png
new file mode 100644
index 000000000..9766030c0
Binary files /dev/null and b/kicker/data/kickoff/right_triangle.png differ
diff --git a/kicker/data/kickoff/search-gradient-topdown.png b/kicker/data/kickoff/search-gradient-topdown.png
new file mode 100644
index 000000000..b13a19290
Binary files /dev/null and b/kicker/data/kickoff/search-gradient-topdown.png differ
diff --git a/kicker/data/kickoff/search-gradient.png b/kicker/data/kickoff/search-gradient.png
new file mode 100644
index 000000000..3478ea18b
Binary files /dev/null and b/kicker/data/kickoff/search-gradient.png differ
diff --git a/kicker/data/kickoff/search-running.mng b/kicker/data/kickoff/search-running.mng
new file mode 100644
index 000000000..9f477c9c3
Binary files /dev/null and b/kicker/data/kickoff/search-running.mng differ
diff --git a/kicker/data/kickoff/search-tab-center.png b/kicker/data/kickoff/search-tab-center.png
new file mode 100644
index 000000000..26ec2f2e9
Binary files /dev/null and b/kicker/data/kickoff/search-tab-center.png differ
diff --git a/kicker/data/kickoff/search-tab-left.png b/kicker/data/kickoff/search-tab-left.png
new file mode 100644
index 000000000..507b41767
Binary files /dev/null and b/kicker/data/kickoff/search-tab-left.png differ
diff --git a/kicker/data/kickoff/search-tab-right.png b/kicker/data/kickoff/search-tab-right.png
new file mode 100644
index 000000000..94a410443
Binary files /dev/null and b/kicker/data/kickoff/search-tab-right.png differ
diff --git a/kicker/data/kickoff/search-tab-top-center.png b/kicker/data/kickoff/search-tab-top-center.png
new file mode 100644
index 000000000..51482ad23
Binary files /dev/null and b/kicker/data/kickoff/search-tab-top-center.png differ
diff --git a/kicker/data/kickoff/search-tab-top-left.png b/kicker/data/kickoff/search-tab-top-left.png
new file mode 100644
index 000000000..97264782a
Binary files /dev/null and b/kicker/data/kickoff/search-tab-top-left.png differ
diff --git a/kicker/data/kickoff/search-tab-top-right.png b/kicker/data/kickoff/search-tab-top-right.png
new file mode 100644
index 000000000..fc80f40c2
Binary files /dev/null and b/kicker/data/kickoff/search-tab-top-right.png differ
diff --git a/kicker/data/kickoff/tab-bottom-left-topdown.png b/kicker/data/kickoff/tab-bottom-left-topdown.png
new file mode 100644
index 000000000..a96a7bf12
Binary files /dev/null and b/kicker/data/kickoff/tab-bottom-left-topdown.png differ
diff --git a/kicker/data/kickoff/tab-bottom-left.png b/kicker/data/kickoff/tab-bottom-left.png
new file mode 100644
index 000000000..fd8a34aca
Binary files /dev/null and b/kicker/data/kickoff/tab-bottom-left.png differ
diff --git a/kicker/data/kickoff/tab-bottom-right-topdown.png b/kicker/data/kickoff/tab-bottom-right-topdown.png
new file mode 100644
index 000000000..d1d80a6b3
Binary files /dev/null and b/kicker/data/kickoff/tab-bottom-right-topdown.png differ
diff --git a/kicker/data/kickoff/tab-bottom-right.png b/kicker/data/kickoff/tab-bottom-right.png
new file mode 100644
index 000000000..86d226b51
Binary files /dev/null and b/kicker/data/kickoff/tab-bottom-right.png differ
diff --git a/kicker/data/kickoff/tab-center-topdown.png b/kicker/data/kickoff/tab-center-topdown.png
new file mode 100644
index 000000000..c35438d91
Binary files /dev/null and b/kicker/data/kickoff/tab-center-topdown.png differ
diff --git a/kicker/data/kickoff/tab-center.png b/kicker/data/kickoff/tab-center.png
new file mode 100644
index 000000000..0ef1f6d34
Binary files /dev/null and b/kicker/data/kickoff/tab-center.png differ
diff --git a/kicker/data/kickoff/tab-left_center.png b/kicker/data/kickoff/tab-left_center.png
new file mode 100644
index 000000000..4c8c39794
Binary files /dev/null and b/kicker/data/kickoff/tab-left_center.png differ
diff --git a/kicker/data/kickoff/tab-right_center.png b/kicker/data/kickoff/tab-right_center.png
new file mode 100644
index 000000000..3df6564f4
Binary files /dev/null and b/kicker/data/kickoff/tab-right_center.png differ
diff --git a/kicker/data/kickoff/tab-top-left-topdown.png b/kicker/data/kickoff/tab-top-left-topdown.png
new file mode 100644
index 000000000..3df580e1d
Binary files /dev/null and b/kicker/data/kickoff/tab-top-left-topdown.png differ
diff --git a/kicker/data/kickoff/tab-top-left.png b/kicker/data/kickoff/tab-top-left.png
new file mode 100644
index 000000000..910967a18
Binary files /dev/null and b/kicker/data/kickoff/tab-top-left.png differ
diff --git a/kicker/data/kickoff/tab-top-right-topdown.png b/kicker/data/kickoff/tab-top-right-topdown.png
new file mode 100644
index 000000000..dd672cad9
Binary files /dev/null and b/kicker/data/kickoff/tab-top-right-topdown.png differ
diff --git a/kicker/data/kickoff/tab-top-right.png b/kicker/data/kickoff/tab-top-right.png
new file mode 100644
index 000000000..e96019d6d
Binary files /dev/null and b/kicker/data/kickoff/tab-top-right.png differ
diff --git a/kicker/kicker/ui/browser_mnu.cpp b/kicker/kicker/ui/browser_mnu.cpp
index 6802e6388..88ce30713 100644
--- a/kicker/kicker/ui/browser_mnu.cpp
+++ b/kicker/kicker/ui/browser_mnu.cpp
@@ -31,6 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <kfileitem.h>
 #include <kglobal.h>
 #include <kglobalsettings.h>
+#include <kconfig.h>
 #include <kiconloader.h>
 #include <kio/global.h>
 #include <klocale.h>
@@ -148,12 +149,14 @@ void PanelBrowserMenu::initialize()
     // only the first part menu got them
     if(_startid == 0 && !_filesOnly) {
        insertTitle(path());
+       KConfig *c = KGlobal::config();
+       c->setGroup("menus");
        insertItem(CICON("kfm"), i18n("Open in File Manager"), this, TQT_SLOT(slotOpenFileManager()));
-        if (kapp->authorize("shell_access"))
-            insertItem(CICON("terminal"), i18n("Open in Terminal"), this, TQT_SLOT(slotOpenTerminal()));
+	if (kapp->authorize("shell_access") && c->readBoolEntry("kickerOpenInTerminalIsVisible",false)) 
+	    insertItem(CICON("terminal"), i18n("Open in Terminal"), this, TQT_SLOT(slotOpenTerminal()));
+    	insertSeparator();
     }
 
-
     bool first_entry = true;
     bool dirfile_separator = false;
     unsigned int item_count = 0;
diff --git a/kicker/kicker/ui/service_mnu.cpp b/kicker/kicker/ui/service_mnu.cpp
index fa18a7038..3042eddfe 100644
--- a/kicker/kicker/ui/service_mnu.cpp
+++ b/kicker/kicker/ui/service_mnu.cpp
@@ -114,6 +114,11 @@ void PanelServiceMenu::fillMenu(KServiceGroup::Ptr& _root,
     TQStringList suppressGenericNames = _root->suppressGenericNames();
 
     KServiceGroup::List::ConstIterator it = _list.begin();
+    KSortableValueList<KSharedPtr<KSycocaEntry>,TQCString> slist;
+    KSortableValueList<KSharedPtr<KSycocaEntry>,TQCString> glist;
+    TQMap<TQString,TQString> specialTitle;
+    TQMap<TQString,TQString> categoryIcon;
+
     bool separatorNeeded = false;
     for (; it != _list.end(); ++it)
     {
@@ -121,19 +126,108 @@ void PanelServiceMenu::fillMenu(KServiceGroup::Ptr& _root,
 
         if (e->isType(KST_KServiceGroup))
         {
+            KServiceGroup::Ptr g(static_cast<KServiceGroup *>(e));
+            if ( KickerSettings::reduceMenuDepth() && g->SuSEshortMenu() ){
+               KServiceGroup::List l = g->entries(true, excludeNoDisplay_ );
+               if ( l.count() == 1 ) {
+                  // the special case, we want to short the menu.
+                  // TOFIX? : this works only for one level
+                  KServiceGroup::List::ConstIterator _it=l.begin();
+                  KSycocaEntry *_e = *_it;
+                  if (_e->isType(KST_KService)) {
+                     KService::Ptr s(static_cast<KService *>(_e));
+		     TQString key;
+                     if ( g->SuSEgeneralDescription() ) {
+			// we use the application name
+                        key = s->name();
+                        if( !s->genericName().isEmpty()) {
+                           if (KickerSettings::menuEntryFormat() == KickerSettings::NameAndDescription)
+                               key = s->name() + " (" + s->genericName() + ")";
+			   else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionAndName)
+                               key = s->genericName() + " (" + s->name() + ")";
+			   else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly)
+                             key = s->genericName();
+                        }
+                     }
+		     else {
+			// we use the normal menu description
+			key = s->name();
+                        if( !s->genericName().isEmpty()) {
+                           if (KickerSettings::menuEntryFormat() == KickerSettings::NameAndDescription)
+                               key = s->name() + " (" + g->caption() + ")";
+			   else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionAndName)
+                               key = g->caption() + " (" + s->name() + ")";
+			   else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly)
+                             key = g->caption();
+                        }
+		     }
+		     specialTitle.insert( _e->name(), key );
+		     categoryIcon.insert( _e->name(), g->icon() );
+                     slist.insert( key.local8Bit(), _e );
+                     // and escape from here
+                     continue;
+                  }
+               }
+            }
+            glist.insert( g->caption().local8Bit(), e );
+        }else if( e->isType(KST_KService)) {
+            KService::Ptr s(static_cast<KService *>(e));
+            TQString name = s->name();
+            if( !s->genericName().isEmpty()) {
+               if (KickerSettings::menuEntryFormat() == KickerSettings::NameAndDescription)
+                   name = s->name() + " (" + s->genericName() + ")";
+	       else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionAndName)
+                   name = s->genericName() + " (" + s->name() + ")";
+	       else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly)
+                   name = s->genericName();
+            }
+            slist.insert( name.local8Bit(), e );
+        } else
+            slist.insert( e->name().local8Bit(), e );
+    }
+
+    _list = _root->SuSEsortEntries( slist, glist, excludeNoDisplay_, true );
+    it = _list.begin();
+
+    for (; it != _list.end(); ++it) {
 
+        KSycocaEntry * e = *it;
+
+        if (e->isType(KST_KServiceGroup)) {
             KServiceGroup::Ptr g(static_cast<KServiceGroup *>(e));
+            if ( KickerSettings::reduceMenuDepth() && g->SuSEshortMenu() ){
+               KServiceGroup::List l = g->entries(true, excludeNoDisplay_ );
+               if ( l.count() == 1 ) {
+ /*               // the special case, we want to short the menu.
+                  // TOFIX? : this works only for one level
+                  KServiceGroup::List::ConstIterator _it=l.begin();
+                  KSycocaEntry *_e = *_it;
+                  if (_e->isType(KST_KService)) {
+                     KService::Ptr s(static_cast<KService *>(_e));
+                     if ( g->SuSEgeneralDescription() )
+                       // we use the application name
+                       insertMenuItem(s, id++, -1, 0, TQString::null, TQString::null, g->icon() );
+                    else
+                       // we use the normal menu description
+                       insertMenuItem(s, id++, -1, 0, TQString::null, g->caption(), g->icon() );
+                     // and escape from here */
+                     continue;
+ //                 }   
+               }      
+            }         
+            // standard sub menu
+                      
             TQString groupCaption = g->caption();
-
+                      
            // Avoid adding empty groups.
             KServiceGroup::Ptr subMenuRoot = KServiceGroup::group(g->relPath());
-
+                      
             int nbChildCount = subMenuRoot->childCount();
             if (nbChildCount == 0 && !g->showEmptyMenu())
-            {
+            {         
                 continue;
-            }
-
+            }         
+                      
             TQString inlineHeaderName = g->showInlineHeader() ? groupCaption : "";
             // Item names may contain ampersands. To avoid them being converted
             // to accelerators, replace them with two ampersands.
@@ -156,7 +250,8 @@ void PanelServiceMenu::fillMenu(KServiceGroup::Ptr& _root,
                         }
 
                         KService::Ptr s(static_cast<KService *>(e1));
-                        insertMenuItem(s, id++, -1, &suppressGenericNames);
+//                        insertMenuItem(s, id++, -1, &suppressGenericNames);
+                        insertMenuItem(s, id++, -1, &suppressGenericNames, TQString::null, specialTitle[s->name()], categoryIcon[s->name()] );
                         continue;
                     }
                 }
@@ -222,7 +317,8 @@ void PanelServiceMenu::fillMenu(KServiceGroup::Ptr& _root,
 
             KService::Ptr s(static_cast<KService *>(e));
             searchMenuItems.insert(id);
-            insertMenuItem(s, id++, -1, &suppressGenericNames);
+//            insertMenuItem(s, id++, -1, &suppressGenericNames);
+            insertMenuItem(s, id++, -1, &suppressGenericNames, TQString::null, specialTitle[s->name()], categoryIcon[s->name()] );
         }
         else if (e->isType(KST_KServiceSeparator))
         {
@@ -304,7 +400,8 @@ void PanelServiceMenu::configChanged()
 void PanelServiceMenu::insertMenuItem(KService::Ptr & s, int nId,
                                       int nIndex/*= -1*/,
                                       const TQStringList *suppressGenericNames /* = 0 */,
-                                      const TQString & aliasname)
+                                      const TQString & aliasname, const TQString & label /*=TQString::NULL*/,
+                                      const TQString & categoryIcon /*=TQString::null*/)
 {
     TQString serviceName = (aliasname.isEmpty() ? s->name() : aliasname).simplifyWhiteSpace();
     TQString comment = s->genericName().simplifyWhiteSpace();
@@ -355,7 +452,15 @@ void PanelServiceMenu::insertMenuItem(KService::Ptr & s, int nId,
     // to accelerators, replace them with two ampersands.
     serviceName.replace("&", "&&");
 
-    int newId = insertItem(KickerLib::menuIconSet(s->icon()), serviceName, nId, nIndex);
+    TQString icon = s->icon();
+    if (icon=="unknown")
+        icon = categoryIcon;
+
+    int newId;
+    if ( label.isEmpty() )
+       newId = insertItem(KickerLib::menuIconSet(s->icon()), serviceName, nId, nIndex);
+    else
+       newId = insertItem(KickerLib::menuIconSet(s->icon()), label, nId, nIndex);
     entryMap_.insert(newId, static_cast<KSycocaEntry*>(s));
 }
 
diff --git a/kicker/kicker/ui/service_mnu.h b/kicker/kicker/ui/service_mnu.h
index 193e4faf8..44e35a6c2 100644
--- a/kicker/kicker/ui/service_mnu.h
+++ b/kicker/kicker/ui/service_mnu.h
@@ -89,7 +89,8 @@ protected slots:
 protected:
     void insertMenuItem(KService::Ptr & s, int nId, int nIndex = -1,
                         const TQStringList *suppressGenericNames=0,
-                        const TQString &aliasname = TQString::null);
+                        const TQString &aliasname = TQString::null,
+                        const TQString &label = TQString::null, const TQString &categoryIcon = TQString::null);
     virtual PanelServiceMenu * newSubMenu(const TQString & label,
                                           const TQString & relPath,
                                           TQWidget * parent, const char * name,
diff --git a/kicker/libkicker/kickerSettings.kcfg b/kicker/libkicker/kickerSettings.kcfg
index ff86c8431..6f7f2427e 100644
--- a/kicker/libkicker/kickerSettings.kcfg
+++ b/kicker/libkicker/kickerSettings.kcfg
@@ -126,6 +126,11 @@
       <default>true</default>
    </entry>
 
+<entry name="ReduceMenuDepth" type="Bool" >
+      <label>Simplify menus with only a single item inside</label>
+      <default>false</default>
+   </entry>
+
 <entry name="MenuEntryHeight" type="Int" >
       <label>Height of menu entries in pixels</label>
       <default>0</default>
diff --git a/kioslave/media/mediaimpl.cpp b/kioslave/media/mediaimpl.cpp
index fb9e01480..b55b37e5d 100644
--- a/kioslave/media/mediaimpl.cpp
+++ b/kioslave/media/mediaimpl.cpp
@@ -281,6 +281,13 @@ bool MediaImpl::ensureMediumMounted(Medium &medium)
 		return m_lastErrorCode==0;
 	}
 
+	if (medium.id().isEmpty())
+	{
+		m_lastErrorCode = KIO::ERR_COULD_NOT_MOUNT;
+		m_lastErrorMessage = i18n("No such medium.");
+		return false;
+	}
+
 	return true;
 }
 
diff --git a/kioslave/media/mediamanager/halbackend.cpp b/kioslave/media/mediamanager/halbackend.cpp
index b6763ee84..7b56d46ad 100644
--- a/kioslave/media/mediamanager/halbackend.cpp
+++ b/kioslave/media/mediamanager/halbackend.cpp
@@ -35,6 +35,7 @@
 #include <kmountpoint.h>
 #include <kmessagebox.h>
 #include <kio/job.h>
+#include <kprotocolinfo.h>
 #include <kstandarddirs.h>
 #include <kprocess.h>
 
@@ -623,6 +624,13 @@ void HALBackend::setVolumeProperties(Medium* medium)
             case LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER:
             {
                 medium->setIconName("ipod" + MOUNT_ICON_SUFFIX);
+
+                if (libhal_device_get_property_QString(m_halContext, driveUdi.latin1(), "info.product") == "iPod" &&
+		         KProtocolInfo::isKnownProtocol( TQString("ipod") ) )
+                {
+                    medium->unmountableState( "ipod:/" );
+                    medium->mountableState(  libhal_volume_is_mounted(halVolume) );
+                }
                 break;
             }
             case LIBHAL_DRIVE_TYPE_CAMERA:
diff --git a/kioslave/smb/kio_smb_auth.cpp b/kioslave/smb/kio_smb_auth.cpp
index d216e1e5b..d4a48239f 100644
--- a/kioslave/smb/kio_smb_auth.cpp
+++ b/kioslave/smb/kio_smb_auth.cpp
@@ -144,6 +144,7 @@ bool SMBSlave::checkPassword(SMBUrl &url)
     if ( openPassDlg(info) ) {
         kdDebug(KIO_SMB) << "openPassDlg returned " << info.username << endl;
         url.setUser(info.username);
+        url.setPass(info.password);
         return true;
     }
     kdDebug(KIO_SMB) << "no value from openPassDlg\n";
diff --git a/kioslave/system/entries/documents.desktop b/kioslave/system/entries/documents.desktop
index 16016e0c5..a2c0fe528 100644
--- a/kioslave/system/entries/documents.desktop
+++ b/kioslave/system/entries/documents.desktop
@@ -1,7 +1,7 @@
 [Desktop Entry]
 Type=Link
 Path[$e]=$( kio_system_documenthelper )
-Icon=folder_important
+Icon=folder_man
 Name=Documents Folder
 Name[af]=Dokument Gids
 Name[ar]=مستنداتي
diff --git a/klipper/klipperrc.desktop b/klipper/klipperrc.desktop
index ba04cf594..5ad72c141 100644
--- a/klipper/klipperrc.desktop
+++ b/klipper/klipperrc.desktop
@@ -232,7 +232,7 @@ Number of commands=5
 Regexp=^https?://.
 
 [Action_1/Command_0]
-Commandline=kfmclient exec %s
+Commandline=kfmclient openURL %s
 Description=Open with &Konqueror
 Description[af]=Maak oop met Konqueror
 Description[ar]=إفتح بــ &Konqueror
@@ -1644,7 +1644,7 @@ Number of commands=5
 Regexp=^ftp://.
 
 [Action_6/Command_0]
-Commandline=kfmclient exec %s
+Commandline=kfmclient openURL %s
 Description=Open with &Konqueror
 Description[af]=Maak oop met Konqueror
 Description[ar]=إفتح بــ &Konqueror
diff --git a/konqueror/Makefile.am b/konqueror/Makefile.am
index 0fd86b2f5..116a7a915 100644
--- a/konqueror/Makefile.am
+++ b/konqueror/Makefile.am
@@ -48,8 +48,8 @@ noinst_HEADERS = KonqMainWindowIface.h KonqViewIface.h delayedinitializer.h \
 	konq_misc.h konq_openurlrequest.h konq_profiledlg.h konq_run.h \
 	konq_view.h konq_viewmgr.h konq_extensionmanager.h version.h
 
-konqueror_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
-konqueror_la_LIBADD = ../libkonq/libkonq.la libkonqueror_intern.la $(LIBMALLOC) $(LIB_KUTILS)
+konqueror_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -lconnectionmanager
+konqueror_la_LIBADD = ../libkonq/libkonq.la libkonqueror_intern.la $(LIBMALLOC) $(LIB_KUTILS) -lconnectionmanager
 
 # Hmm, this experiment of a static konq failed, don't trust it...
 # (but feel free to fix it :)
diff --git a/konqueror/konq_combo.cc b/konqueror/konq_combo.cc
index 86747ebde..0a73e6c83 100644
--- a/konqueror/konq_combo.cc
+++ b/konqueror/konq_combo.cc
@@ -128,6 +128,9 @@ KonqCombo::KonqCombo( TQWidget *parent, const char *name )
     connect( this, TQT_SIGNAL(activated( const TQString& )),
              TQT_SLOT(slotActivated( const TQString& )) );
 
+    setHistoryEditorEnabled( true ); 
+    connect( this, TQT_SIGNAL(removed( const TQString&) ), TQT_SLOT(slotRemoved( const TQString& )) );
+
     if ( !kapp->dcopClient()->isAttached() )
         kapp->dcopClient()->attach();
 }
@@ -507,6 +510,15 @@ void KonqCombo::slotCleared()
     kapp->dcopClient()->send( "konqueror*", "KonquerorIface", "comboCleared(TQCString)", data);
 }
 
+void KonqCombo::slotRemoved( const TQString& item )
+{
+    TQByteArray data;
+    TQDataStream s( data, IO_WriteOnly );
+    s << item << kapp->dcopClient()->defaultObject();
+    kapp->dcopClient()->send( "konqueror*", "KonquerorIface",
+                               "removeFromCombo(TQString,TQCString)", data);
+}
+
 void KonqCombo::removeURL( const TQString& url )
 {
     setUpdatesEnabled( false );
diff --git a/konqueror/konq_combo.h b/konqueror/konq_combo.h
index dfb2778dc..3650eb9a4 100644
--- a/konqueror/konq_combo.h
+++ b/konqueror/konq_combo.h
@@ -87,6 +87,7 @@ signals:
 
 private slots:
     void slotCleared();
+    void slotRemoved( const TQString& item );
     void slotSetIcon( int index );
     void slotActivated( const TQString& text );
 
diff --git a/konqueror/konq_frame.cc b/konqueror/konq_frame.cc
index 77310ebbc..149a2f92d 100644
--- a/konqueror/konq_frame.cc
+++ b/konqueror/konq_frame.cc
@@ -34,6 +34,7 @@
 #include <kprogress.h>
 #include <klocale.h>
 #include <ksqueezedtextlabel.h>
+#include <networkstatusindicator.h>
 
 #include "konq_events.h"
 #include "konq_frame.h"
@@ -97,6 +98,10 @@ KonqFrameStatusBar::KonqFrameStatusBar( KonqFrame *_parent, const char *_name )
     m_progressBar->hide();
     addWidget( m_progressBar, 0, true /*permanent->right align*/ );
 
+    StatusBarNetworkStatusIndicator * indicator = new StatusBarNetworkStatusIndicator( this, "networkstatusindicator" );
+    addWidget( indicator, 0, false );
+    indicator->init();
+
     fontChange(TQFont());
     installEventFilter( this );
 }
diff --git a/konsole/other/x11r5.keytab b/konsole/other/x11r5.keytab
index 75ba06ec4..c731807ca 100644
--- a/konsole/other/x11r5.keytab
+++ b/konsole/other/x11r5.keytab
@@ -32,10 +32,10 @@ key Left  -Shift   : "\EOD"
 
 key Enter          : "\r"
 
-key Home           : "\E[1~"
+key Home           : "\E[H"
 key Insert-Shift   : "\E[2~"
 key Delete         : "\E[3~"
-key End            : "\E[4~"
+key End            : "\E[F"
 key Prior -Shift   : "\E[5~"
 key Next  -Shift   : "\E[6~"
 
diff --git a/kscreensaver/Makefile.am b/kscreensaver/Makefile.am
index 75cf37640..2823d4e17 100644
--- a/kscreensaver/Makefile.am
+++ b/kscreensaver/Makefile.am
@@ -3,13 +3,13 @@
 
 AM_CPPFLAGS = -UQT_NO_ASCII_CAST
 
-INCLUDES = $(all_includes)
+INCLUDES = $(GLINC) $(all_includes)
 AM_LDFLAGS = $(all_libraries) $(KDE_RPATH)
 
 bin_PROGRAMS = krandom.kss kblankscrn.kss
 
 krandom_kss_SOURCES = random.cpp
-krandom_kss_LDADD = $(LIB_KDEUI) -lm
+krandom_kss_LDADD = $(LIB_KDEUI) $(GLLIB) -lm
 
 kblankscrn_kss_SOURCES = blankscrn.cpp
 kblankscrn_kss_LDADD = $(LIB_KDEUI) -lkscreensaver -lm 
diff --git a/kscreensaver/random.cpp b/kscreensaver/random.cpp
index c1cd8dcad..cd984a145 100644
--- a/kscreensaver/random.cpp
+++ b/kscreensaver/random.cpp
@@ -1,4 +1,4 @@
-//-----------------------------------------------------------------------------
+ //-----------------------------------------------------------------------------
 //
 // Screen savers for KDE
 //
@@ -19,6 +19,7 @@
 #include <tqframe.h>
 #include <tqcheckbox.h>
 #include <tqwidget.h>
+#include <tqfileinfo.h>
 
 #include <kapplication.h>
 #include <kstandarddirs.h>
@@ -36,7 +37,7 @@
 
 #define MAX_ARGS    20
 
-void usage(char *name)
+static void usage(char *name)
 {
 	puts(i18n("Usage: %1 [-setup] [args]\n"
 				"Starts a random screen saver.\n"
@@ -60,6 +61,43 @@ static const KCmdLineOptions options[] =
 
 //----------------------------------------------------------------------------
 
+#ifdef HAVE_GLXCHOOSEVISUAL
+#include <GL/glx.h>
+#endif
+
+//-------------------------------------
+bool hasDirectRendering () {
+    Display *dpy = TQApplication::desktop()->x11Display();
+
+#ifdef HAVE_GLXCHOOSEVISUAL
+    int attribSingle[] = {
+        GLX_RGBA,
+        GLX_RED_SIZE,   1,
+        GLX_GREEN_SIZE, 1,
+        GLX_BLUE_SIZE,  1,
+        None
+    };
+    XVisualInfo* visinfo = glXChooseVisual (
+        dpy, TQApplication::desktop()->primaryScreen(), attribSingle
+    );
+    if (visinfo) {
+        GLXContext ctx = glXCreateContext ( dpy, visinfo, NULL, True );
+        if (glXIsDirect(dpy, ctx)) {
+            glXDestroyContext (dpy,ctx);
+            return true;
+        }
+        glXDestroyContext (dpy,ctx);
+        return false;
+    } else {
+        return false;
+    }
+#else
+#error no GL?
+    return false;
+#endif
+
+}
+
 int main(int argc, char *argv[])
 {
 	KLocale::setMainCatalogue("kscreensaver");
@@ -103,55 +141,63 @@ int main(int argc, char *argv[])
 
 	KConfig type("krandom.kssrc");
 	type.setGroup("Settings");
-	bool opengl = type.readBoolEntry("OpenGL");
+	bool opengl = type.readBoolEntry("OpenGL", hasDirectRendering());
+        kdDebug() << "hasOPEN " << opengl << endl;
 	bool manipulatescreen = type.readBoolEntry("ManipulateScreen");
         bool fortune = !KStandardDirs::findExe("fortune").isEmpty();
+        TQStringList defaults = type.readListEntry( "Defaults" );
+        TQMap<TQString, int> def_numbers;
+        for ( TQStringList::ConstIterator it = defaults.begin(); it != defaults.end(); ++it ) {
+            int index = ( *it ).find( ':' );
+            if ( index == -1 )
+                def_numbers[*it] = 1;
+            else
+                def_numbers[( *it ).left( index )] = ( *it ).mid( index + 1 ).toInt();
+        }
 
 	for (uint i = 0; i < tempSaverFileList.count(); i++)
 	{
-		kdDebug() << "Looking at " << tempSaverFileList[i] << endl;
+                int howoften = 1;
+                if ( defaults.count() != 0 ) {
+                    TQFileInfo fi( tempSaverFileList[i] );
+                    if ( def_numbers.contains( fi.fileName() ) )
+                        howoften = def_numbers[fi.fileName()];
+                    else
+                        howoften = 0;
+                }
+
 		KDesktopFile saver(tempSaverFileList[i], true);
-		if(!saver.tryExec())
-			continue;
-		kdDebug() << "read X-KDE-Type" << endl;
+                if (!saver.tryExec())
+                    continue;
 		TQString saverType = saver.readEntry("X-KDE-Type");
-
-		if (saverType.isEmpty()) // no X-KDE-Type defined so must be OK
-		{
-			saverFileList.append(tempSaverFileList[i]);
-		}
-		else
-		{
+		if (!saverType.isEmpty()) // no X-KDE-Type defined so must be OK
+                {
 			TQStringList saverTypes = TQStringList::split(";", saverType);
 			for (TQStringList::ConstIterator it =  saverTypes.begin(); it != saverTypes.end(); ++it )
 			{
-				kdDebug() << "saverTypes is "<< *it << endl;
 				if (*it == "ManipulateScreen")
 				{
-					if (manipulatescreen)
-					{
-						saverFileList.append(tempSaverFileList[i]);
-					}
+					if (!manipulatescreen)
+                                            howoften = 0;
 				}
 				else
 				if (*it == "OpenGL")
 				{
-					if (opengl)
-					{
-						saverFileList.append(tempSaverFileList[i]);
-					}
+					if (!opengl)
+                                            howoften = 0;
 				}
 				if (*it == "Fortune")
 				{
-					if (fortune)
-					{
-						saverFileList.append(tempSaverFileList[i]);
-					}
+					if (!fortune)
+                                            howoften = 0;
 				}
 
 			}
 		}
+                for ( int j = 0; j < howoften; ++j )
+                    saverFileList.append(tempSaverFileList[i]);
 	}
+        kdDebug() << "final " << saverFileList << endl;
 
 	KRandomSequence rnd;
 	int indx = rnd.getLong(saverFileList.count());
@@ -229,7 +275,7 @@ KRandomSetup::KRandomSetup( TQWidget *parent, const char *name )
 
 	KConfig config("krandom.kssrc");
 	config.setGroup("Settings");
-	openGL->setChecked(config.readBoolEntry("OpenGL", true));
+	openGL->setChecked(config.readBoolEntry("OpenGL", hasDirectRendering()));
 	manipulateScreen->setChecked(config.readBoolEntry("ManipulateScreen", true));
 }
 
diff --git a/ksmserver/KSMServerInterface.h b/ksmserver/KSMServerInterface.h
index 52fdf0942..a628b92ba 100644
--- a/ksmserver/KSMServerInterface.h
+++ b/ksmserver/KSMServerInterface.h
@@ -22,6 +22,8 @@ k_dcop:
   
   virtual void suspendStartup( TQCString ) = 0;
   virtual void resumeStartup( TQCString ) = 0;
+
+  virtual void logoutTimed( int, int, TQString ) = 0;
 };
 
 #endif
diff --git a/ksmserver/Makefile.am b/ksmserver/Makefile.am
index 62f9d8976..19b328bc5 100644
--- a/ksmserver/Makefile.am
+++ b/ksmserver/Makefile.am
@@ -28,7 +28,7 @@ ksmserver_la_METASOURCES = AUTO
 # Order is important for --enable-final!
 ksmserver_la_SOURCES = main.cpp server.cpp shutdowndlg.cpp \
 	legacy.cpp startup.cpp shutdown.cpp client.cpp \
-	KSMServerInterface.skel server.skel
+	KSMServerInterface.skel server.skel timed.ui
 
 ksmserver_la_LDFLAGS = $(all_libraries) -avoid-version -module
 ksmserver_la_LIBADD = ../kdmlib/libdmctl.la $(LIB_KDEUI) $(HAL_LIBS) $(DBUS_LIBS)
@@ -42,7 +42,7 @@ updatedir = $(kde_datadir)/kconf_update
 
 
 EXTRA_PROGRAMS = testsh
-testsh_SOURCES = test.cpp
+testsh_SOURCES = test.cpp timed.ui
 testsh_LDFLAGS = $(all_libraries) $(KDE_RPATH)
 testsh_LDADD = $(LIB_KDEUI) shutdowndlg.lo ../kdmlib/libdmctl.la $(HAL_LIBS) $(DBUS_LIBS)
 
diff --git a/ksmserver/server.h b/ksmserver/server.h
index 3d5904e53..0fc900042 100644
--- a/ksmserver/server.h
+++ b/ksmserver/server.h
@@ -85,6 +85,7 @@ public:
     // public API
     void restoreSession( TQString sessionName );
     void startDefaultSession();
+
     void shutdown( KApplication::ShutdownConfirm confirm,
                    KApplication::ShutdownType sdtype,
                    KApplication::ShutdownMode sdmode );
@@ -92,6 +93,11 @@ public:
     virtual void suspendStartup( TQCString app );
     virtual void resumeStartup( TQCString app );
 
+    bool checkStatus( bool &logoutConfirmed, bool &maysd, 
+		      KApplication::ShutdownConfirm confirm,
+		      KApplication::ShutdownType sdtype,
+		      KApplication::ShutdownMode sdmode );
+
 public slots:
     void cleanUp();
 
@@ -142,6 +148,11 @@ private:
     bool defaultSession() const; // empty session
     void setupXIOErrorHandler();
 
+    void shutdownInternal( KApplication::ShutdownConfirm confirm,
+			   KApplication::ShutdownType sdtype,
+			   KApplication::ShutdownMode sdmode,
+			   TQString bootOption = TQString::null );
+
     void performLegacySessionSave();
     void storeLegacySession( KConfig* config );
     void restoreLegacySession( KConfig* config );
@@ -157,6 +168,7 @@ private:
 
     // public dcop interface
     void logout( int, int, int );
+    virtual void logoutTimed( int, int, TQString );
     TQStringList sessionList();
     TQString currentSession();
     void saveCurrentSession();
diff --git a/ksmserver/shutdown.cpp b/ksmserver/shutdown.cpp
index 16fab8b4d..a850d40be 100644
--- a/ksmserver/shutdown.cpp
+++ b/ksmserver/shutdown.cpp
@@ -93,14 +93,16 @@ void KSMServer::logout( int confirm, int sdtype, int sdmode )
               (KApplication::ShutdownMode)sdmode );
 }
 
-void KSMServer::shutdown( KApplication::ShutdownConfirm confirm,
-    KApplication::ShutdownType sdtype, KApplication::ShutdownMode sdmode )
+bool KSMServer::checkStatus( bool &logoutConfirmed, bool &maysd,
+                             KApplication::ShutdownConfirm confirm,
+                             KApplication::ShutdownType sdtype,
+                             KApplication::ShutdownMode sdmode )
 {
     pendingShutdown.stop();
     if( dialogActive )
-        return;
+        return false;
     if( state >= Shutdown ) // already performing shutdown
-        return;
+        return false;
     if( state != Idle ) // performing startup
     {
     // perform shutdown as soon as startup is finished, in order to avoid saving partial session
@@ -111,25 +113,44 @@ void KSMServer::shutdown( KApplication::ShutdownConfirm confirm,
             pendingShutdown_sdtype = sdtype;
             pendingShutdown_sdmode = sdmode;
         }
-        return;
+        return false;
     }
 
     KConfig *config = KGlobal::config();
     config->reparseConfiguration(); // config may have changed in the KControl module
 
     config->setGroup("General" );
-    bool logoutConfirmed =
+    logoutConfirmed =
         (confirm == KApplication::ShutdownConfirmYes) ? false :
-       (confirm == KApplication::ShutdownConfirmNo) ? true :
-                  !config->readBoolEntry( "confirmLogout", true );
-    bool maysd = false;
+        (confirm == KApplication::ShutdownConfirmNo) ? true :
+        !config->readBoolEntry( "confirmLogout", true );
+    maysd = false;
     if (config->readBoolEntry( "offerShutdown", true ) && DM().canShutdown())
         maysd = true;
     if (!maysd) {
         if (sdtype != KApplication::ShutdownTypeNone &&
             sdtype != KApplication::ShutdownTypeDefault &&
             logoutConfirmed)
-            return; /* unsupported fast shutdown */
+            return false; /* unsupported fast shutdown */
+    }
+
+    return true;
+}
+
+void KSMServer::shutdownInternal( KApplication::ShutdownConfirm confirm,
+                                  KApplication::ShutdownType sdtype,
+                                  KApplication::ShutdownMode sdmode,
+                                  TQString bopt )
+{
+    bool maysd = false;
+    bool logoutConfirmed = false;
+    if ( !checkStatus( logoutConfirmed, maysd, confirm, sdtype, sdmode ) )
+        return;
+
+    KConfig *config = KGlobal::config();
+
+    config->setGroup("General" );
+    if (!maysd) {
         sdtype = KApplication::ShutdownTypeNone;
     } else if (sdtype == KApplication::ShutdownTypeDefault)
         sdtype = (KApplication::ShutdownType)
@@ -138,7 +159,6 @@ void KSMServer::shutdown( KApplication::ShutdownConfirm confirm,
         sdmode = KApplication::ShutdownModeInteractive;
 
     dialogActive = true;
-    TQString bopt;
     if ( !logoutConfirmed ) {
         KSMShutdownFeedback::start(); // make the screen gray
         logoutConfirmed =
@@ -204,6 +224,42 @@ void KSMServer::shutdown( KApplication::ShutdownConfirm confirm,
     dialogActive = false;
 }
 
+void KSMServer::shutdown( KApplication::ShutdownConfirm confirm,
+    KApplication::ShutdownType sdtype, KApplication::ShutdownMode sdmode )
+{
+    shutdownInternal( confirm, sdtype, sdmode );
+}
+
+#include <kmessagebox.h>
+
+void KSMServer::logoutTimed( int sdtype, int sdmode, TQString bootOption )
+{
+    int confirmDelay;
+
+    KConfig* config = KGlobal::config();
+    config->setGroup( "General" );
+
+    if ( sdtype == KApplication::ShutdownTypeHalt )
+        confirmDelay = config->readNumEntry( "confirmShutdownDelay", 31 );
+    else if ( sdtype == KApplication::ShutdownTypeReboot )
+        confirmDelay = config->readNumEntry( "confirmRebootDelay", 31 );
+    else
+        confirmDelay = config->readNumEntry( "confirmLogoutDelay", 31 );
+
+    bool result = true;
+    if (confirmDelay) {
+        KSMShutdownFeedback::start(); // make the screen gray
+        result = KSMDelayedMessageBox::showTicker( (KApplication::ShutdownType)sdtype, bootOption, confirmDelay );
+        KSMShutdownFeedback::stop(); // make the screen become normal again
+    }
+
+    if ( result )
+        shutdownInternal( KApplication::ShutdownConfirmNo,
+                          (KApplication::ShutdownType)sdtype,
+                          (KApplication::ShutdownMode)sdmode,
+                           bootOption );
+}
+
 void KSMServer::pendingShutdownTimeout()
 {
     shutdown( pendingShutdown_confirm, pendingShutdown_sdtype, pendingShutdown_sdmode );
diff --git a/ksmserver/shutdowndlg.cpp b/ksmserver/shutdowndlg.cpp
index 7b0493559..f6295a158 100644
--- a/ksmserver/shutdowndlg.cpp
+++ b/ksmserver/shutdowndlg.cpp
@@ -29,6 +29,7 @@ Copyright (C) 2000 Matthias Ettrich <ettrich@kde.org>
 #include <tqregexp.h>
 
 #include <klocale.h>
+#include <kconfig.h>
 #include <kapplication.h>
 #include <kdebug.h>
 #include <kpushbutton.h>
@@ -340,6 +341,7 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent,
 		buttonlay->addStretch( 1 );
 		// End session
 		KPushButton* btnLogout = new KPushButton( KGuiItem( i18n("&End Current Session"), "undo"), frame );
+                TQToolTip::add( btnLogout, i18n( "<qt><h3>End Current Session</h3><p>Log out of the current session to login with a different user</p></qt>" ) );
 		btnFont = btnLogout->font();
 		buttonlay->addWidget( btnLogout );
 		connect(btnLogout, TQT_SIGNAL(clicked()), TQT_SLOT(slotLogout()));
@@ -510,14 +512,16 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent,
 		{
 			// Shutdown
 			KPushButton* btnHalt = new KPushButton( KGuiItem( i18n("&Turn Off Computer"), "exit"), frame );
+        TQToolTip::add( btnHalt, i18n( "<qt><h3>Turn Off Computer</h3><p>Log out of the current session and turn off the computer</p></qt>" ) );
 			btnHalt->setFont( btnFont );
 			buttonlay->addWidget( btnHalt );
 			connect(btnHalt, TQT_SIGNAL(clicked()), TQT_SLOT(slotHalt()));
-			if ( sdtype == KApplication::ShutdownTypeHalt )
+        if ( sdtype == KApplication::ShutdownTypeHalt || getenv("KDM_AUTOLOGIN") ) 
 				btnHalt->setFocus();
 	
 			// Reboot
 			KSMDelayedPushButton* btnReboot = new KSMDelayedPushButton( KGuiItem( i18n("&Restart Computer"), "reload"), frame );
+        TQToolTip::add( btnReboot, i18n( "<qt><h3>Restart Computer</h3><p>Log out of the current session and restart the computer</p><p>Hold the mouse button or the space bar for a short while to get a list of options what to boot</p></qt>" ) );
 			btnReboot->setFont( btnFont );
 			buttonlay->addWidget( btnReboot );
 	
@@ -761,6 +765,70 @@ void KSMDelayedPushButton::slotTimeout()
   setDown(false);
 }
 
+KSMDelayedMessageBox::KSMDelayedMessageBox( KApplication::ShutdownType sdtype, const TQString &bootOption, int confirmDelay )
+    : TimedLogoutDlg( 0, 0, true, WType_Popup ), m_remaining(confirmDelay)
+{
+    if ( sdtype == KApplication::ShutdownTypeHalt )
+    {
+        m_title->setText( i18n( "Would you like to turn off your computer?" ) );
+        m_template = i18n( "This computer will turn off automatically\n"
+                           "after %1 seconds." );
+        m_logo->setPixmap( BarIcon( "exit", 48 ) );
+    } else if ( sdtype == KApplication::ShutdownTypeReboot )
+    {
+        if (bootOption.isEmpty())
+            m_title->setText( i18n( "Would you like to reboot your computer?" ) );
+        else
+            m_title->setText( i18n( "Would you like to reboot to \"%1\"?" ).arg(bootOption) );
+        m_template = i18n( "This computer will reboot automatically\n"
+                           "after %1 seconds." );
+        m_logo->setPixmap( BarIcon( "reload", 48 ) );
+    } else {
+        m_title->setText( i18n( "Would you like to end your current session?" ) );
+        m_template = i18n( "This session will end\n"
+                           "after %1 seconds automatically." );
+        m_logo->setPixmap( BarIcon( "previous", 48 ) );
+    }
+
+    updateText();
+    adjustSize();
+    if (  double( height() ) / width() < 0.25 )
+    {
+        setFixedHeight( qRound( width() * 0.3 ) );
+        adjustSize();
+    }
+    TQTimer *timer = new TQTimer( this );
+    timer->start( 1000 );
+    connect( timer, TQT_SIGNAL( timeout() ), TQT_SLOT( updateText() ) );
+    KDialog::centerOnScreen(this);
+}
+
+void KSMDelayedMessageBox::updateText()
+{
+    m_remaining--;
+    if ( m_remaining == 0 )
+    {
+        accept();
+        return;
+    }
+    m_text->setText( m_template.arg( m_remaining ) );
+}
+
+bool KSMDelayedMessageBox::showTicker( KApplication::ShutdownType sdtype, const TQString &bootOption, int confirmDelay )
+{
+    kapp->enableStyles();
+    KSMDelayedMessageBox msg( sdtype, bootOption, confirmDelay );
+    TQSize sh = msg.sizeHint();
+    TQRect rect = KGlobalSettings::desktopGeometry(TQCursor::pos());
+
+    msg.move(rect.x() + (rect.width() - sh.width())/2,
+            rect.y() + (rect.height() - sh.height())/2);
+    bool result = msg.exec();
+
+    kapp->disableStyles();
+    return result;
+}
+
 KSMPushButton::KSMPushButton( const KGuiItem &item,
 					    TQWidget *parent,
 					    const char *name)
diff --git a/ksmserver/shutdowndlg.h b/ksmserver/shutdowndlg.h
index a1d720669..79ee8ca37 100644
--- a/ksmserver/shutdowndlg.h
+++ b/ksmserver/shutdowndlg.h
@@ -26,6 +26,7 @@ class TQString;
 class KAction;
 
 
+#include "timed.h"
 #include <kapplication.h>
 #include <kpixmapio.h>
 
@@ -165,4 +166,22 @@ class FlatButton : public QToolButton
 
 
 
+class TQLabel;
+
+class  KSMDelayedMessageBox : public TimedLogoutDlg
+{
+    Q_OBJECT
+
+public:
+    KSMDelayedMessageBox( KApplication::ShutdownType sdtype, const TQString &bootOption, int confirmDelay );
+    static bool showTicker( KApplication::ShutdownType sdtype, const TQString &bootOption, int confirmDelay );
+
+protected slots:
+    void updateText();
+
+private:
+    TQString m_template;
+    int m_remaining;
+};
+
 #endif
diff --git a/ksmserver/test.cpp b/ksmserver/test.cpp
index 846c449db..8f248725f 100644
--- a/ksmserver/test.cpp
+++ b/ksmserver/test.cpp
@@ -14,11 +14,16 @@ main(int argc, char *argv[])
    a.iconLoader()->addAppDir("ksmserver");
    KSMShutdownFeedback::start();
 
+   // ShutdownTypeNone == Logout == 0
+   // ShutdownTypeReboot == 1
+   // ShutdownTypeHalt == 2
    KApplication::ShutdownType sdtype = KApplication::ShutdownTypeNone;
    TQString bopt;
+   KSMDelayedMessageBox::showTicker( sdtype );
+   /*
    (void)KSMShutdownDlg::confirmShutdown( true,
                                           sdtype,
-                                          bopt );
+                                          bopt );*/
 /*   (void)KSMShutdownDlg::confirmShutdown( false,
                                           sdtype,
                                           bopt ); */
diff --git a/ksmserver/timed.ui b/ksmserver/timed.ui
new file mode 100644
index 000000000..23d7aa2a0
--- /dev/null
+++ b/ksmserver/timed.ui
@@ -0,0 +1,352 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>TimedLogoutDlg</class>
+<widget class="QDialog">
+    <property name="name">
+        <cstring>TimedLogoutDlg</cstring>
+    </property>
+    <property name="geometry">
+        <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>381</width>
+            <height>131</height>
+        </rect>
+    </property>
+    <property name="sizePolicy">
+        <sizepolicy>
+            <hsizetype>5</hsizetype>
+            <vsizetype>5</vsizetype>
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+        </sizepolicy>
+    </property>
+    <property name="caption">
+        <string>Confirmation</string>
+    </property>
+    <vbox>
+        <property name="name">
+            <cstring>unnamed</cstring>
+        </property>
+        <property name="margin">
+            <number>0</number>
+        </property>
+        <property name="spacing">
+            <number>0</number>
+        </property>
+        <widget class="QFrame">
+            <property name="name">
+                <cstring>frame3</cstring>
+            </property>
+            <property name="sizePolicy">
+                <sizepolicy>
+                    <hsizetype>5</hsizetype>
+                    <vsizetype>5</vsizetype>
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                </sizepolicy>
+            </property>
+            <property name="frameShape">
+                <enum>StyledPanel</enum>
+            </property>
+            <property name="frameShadow">
+                <enum>Raised</enum>
+            </property>
+            <property name="lineWidth">
+                <number>2</number>
+            </property>
+            <property name="margin">
+                <number>0</number>
+            </property>
+            <property name="midLineWidth">
+                <number>0</number>
+            </property>
+            <hbox>
+                <property name="name">
+                    <cstring>unnamed</cstring>
+                </property>
+                <widget class="QLayoutWidget">
+                    <property name="name">
+                        <cstring>layout10</cstring>
+                    </property>
+                    <vbox>
+                        <property name="name">
+                            <cstring>unnamed</cstring>
+                        </property>
+                        <property name="margin">
+                            <number>0</number>
+                        </property>
+                        <property name="spacing">
+                            <number>0</number>
+                        </property>
+                        <widget class="QLayoutWidget">
+                            <property name="name">
+                                <cstring>layout8</cstring>
+                            </property>
+                            <hbox>
+                                <property name="name">
+                                    <cstring>unnamed</cstring>
+                                </property>
+                                <widget class="QLayoutWidget">
+                                    <property name="name">
+                                        <cstring>layout6</cstring>
+                                    </property>
+                                    <vbox>
+                                        <property name="name">
+                                            <cstring>unnamed</cstring>
+                                        </property>
+                                        <property name="margin">
+                                            <number>0</number>
+                                        </property>
+                                        <property name="spacing">
+                                            <number>0</number>
+                                        </property>
+                                        <spacer>
+                                            <property name="name">
+                                                <cstring>spacer3_2</cstring>
+                                            </property>
+                                            <property name="orientation">
+                                                <enum>Vertical</enum>
+                                            </property>
+                                            <property name="sizeType">
+                                                <enum>MinimumExpanding</enum>
+                                            </property>
+                                            <property name="sizeHint">
+                                                <size>
+                                                    <width>20</width>
+                                                    <height>2</height>
+                                                </size>
+                                            </property>
+                                        </spacer>
+                                        <widget class="QLabel">
+                                            <property name="name">
+                                                <cstring>m_logo</cstring>
+                                            </property>
+                                            <property name="sizePolicy">
+                                                <sizepolicy>
+                                                    <hsizetype>1</hsizetype>
+                                                    <vsizetype>1</vsizetype>
+                                                    <horstretch>0</horstretch>
+                                                    <verstretch>0</verstretch>
+                                                </sizepolicy>
+                                            </property>
+                                            <property name="minimumSize">
+                                                <size>
+                                                    <width>48</width>
+                                                    <height>48</height>
+                                                </size>
+                                            </property>
+                                            <property name="scaledContents">
+                                                <bool>true</bool>
+                                            </property>
+                                        </widget>
+                                        <spacer>
+                                            <property name="name">
+                                                <cstring>spacer3</cstring>
+                                            </property>
+                                            <property name="orientation">
+                                                <enum>Vertical</enum>
+                                            </property>
+                                            <property name="sizeType">
+                                                <enum>MinimumExpanding</enum>
+                                            </property>
+                                            <property name="sizeHint">
+                                                <size>
+                                                    <width>20</width>
+                                                    <height>2</height>
+                                                </size>
+                                            </property>
+                                        </spacer>
+                                    </vbox>
+                                </widget>
+                                <widget class="QLayoutWidget">
+                                    <property name="name">
+                                        <cstring>layout7</cstring>
+                                    </property>
+                                    <vbox>
+                                        <property name="name">
+                                            <cstring>unnamed</cstring>
+                                        </property>
+                                        <property name="margin">
+                                            <number>7</number>
+                                        </property>
+                                        <widget class="QLabel">
+                                            <property name="name">
+                                                <cstring>m_title</cstring>
+                                            </property>
+                                            <property name="sizePolicy">
+                                                <sizepolicy>
+                                                    <hsizetype>7</hsizetype>
+                                                    <vsizetype>0</vsizetype>
+                                                    <horstretch>0</horstretch>
+                                                    <verstretch>0</verstretch>
+                                                </sizepolicy>
+                                            </property>
+                                            <property name="font">
+                                                <font>
+                                                    <bold>1</bold>
+                                                </font>
+                                            </property>
+                                            <property name="text">
+                                                <string>Would you like to shutdown your computer?</string>
+                                            </property>
+                                            <property name="textFormat">
+                                                <enum>PlainText</enum>
+                                            </property>
+                                            <property name="alignment">
+                                                <set>AlignVCenter|AlignLeft</set>
+                                            </property>
+                                        </widget>
+                                        <widget class="QLabel">
+                                            <property name="name">
+                                                <cstring>m_text</cstring>
+                                            </property>
+                                            <property name="sizePolicy">
+                                                <sizepolicy>
+                                                    <hsizetype>7</hsizetype>
+                                                    <vsizetype>5</vsizetype>
+                                                    <horstretch>0</horstretch>
+                                                    <verstretch>0</verstretch>
+                                                </sizepolicy>
+                                            </property>
+                                            <property name="text">
+                                                <string>If you do not act, your computer will shutdown
+after X automatically.</string>
+                                            </property>
+                                            <property name="textFormat">
+                                                <enum>RichText</enum>
+                                            </property>
+                                            <property name="alignment">
+                                                <set>WordBreak|AlignVCenter</set>
+                                            </property>
+                                        </widget>
+                                        <spacer>
+                                            <property name="name">
+                                                <cstring>spacer4</cstring>
+                                            </property>
+                                            <property name="orientation">
+                                                <enum>Vertical</enum>
+                                            </property>
+                                            <property name="sizeType">
+                                                <enum>Preferred</enum>
+                                            </property>
+                                            <property name="sizeHint">
+                                                <size>
+                                                    <width>30</width>
+                                                    <height>0</height>
+                                                </size>
+                                            </property>
+                                        </spacer>
+                                    </vbox>
+                                </widget>
+                            </hbox>
+                        </widget>
+                        <widget class="QLayoutWidget">
+                            <property name="name">
+                                <cstring>layout9</cstring>
+                            </property>
+                            <hbox>
+                                <property name="name">
+                                    <cstring>unnamed</cstring>
+                                </property>
+                                <spacer>
+                                    <property name="name">
+                                        <cstring>spacer2</cstring>
+                                    </property>
+                                    <property name="orientation">
+                                        <enum>Horizontal</enum>
+                                    </property>
+                                    <property name="sizeType">
+                                        <enum>Expanding</enum>
+                                    </property>
+                                    <property name="sizeHint">
+                                        <size>
+                                            <width>90</width>
+                                            <height>20</height>
+                                        </size>
+                                    </property>
+                                </spacer>
+                                <widget class="QPushButton">
+                                    <property name="name">
+                                        <cstring>pushButton1</cstring>
+                                    </property>
+                                    <property name="text">
+                                        <string>Confirm</string>
+                                    </property>
+                                    <property name="on">
+                                        <bool>false</bool>
+                                    </property>
+                                </widget>
+                                <spacer>
+                                    <property name="name">
+                                        <cstring>spacer2_2</cstring>
+                                    </property>
+                                    <property name="orientation">
+                                        <enum>Horizontal</enum>
+                                    </property>
+                                    <property name="sizeType">
+                                        <enum>Expanding</enum>
+                                    </property>
+                                    <property name="sizeHint">
+                                        <size>
+                                            <width>90</width>
+                                            <height>20</height>
+                                        </size>
+                                    </property>
+                                </spacer>
+                                <widget class="QPushButton">
+                                    <property name="name">
+                                        <cstring>pushButton2</cstring>
+                                    </property>
+                                    <property name="sizePolicy">
+                                        <sizepolicy>
+                                            <hsizetype>1</hsizetype>
+                                            <vsizetype>5</vsizetype>
+                                            <horstretch>0</horstretch>
+                                            <verstretch>0</verstretch>
+                                        </sizepolicy>
+                                    </property>
+                                    <property name="text">
+                                        <string>Cancel</string>
+                                    </property>
+                                </widget>
+                                <spacer>
+                                    <property name="name">
+                                        <cstring>spacer2_2_2</cstring>
+                                    </property>
+                                    <property name="orientation">
+                                        <enum>Horizontal</enum>
+                                    </property>
+                                    <property name="sizeType">
+                                        <enum>Expanding</enum>
+                                    </property>
+                                    <property name="sizeHint">
+                                        <size>
+                                            <width>90</width>
+                                            <height>20</height>
+                                        </size>
+                                    </property>
+                                </spacer>
+                            </hbox>
+                        </widget>
+                    </vbox>
+                </widget>
+            </hbox>
+        </widget>
+    </vbox>
+</widget>
+<connections>
+    <connection>
+        <sender>pushButton1</sender>
+        <signal>clicked()</signal>
+        <receiver>TimedLogoutDlg</receiver>
+        <slot>accept()</slot>
+    </connection>
+    <connection>
+        <sender>pushButton2</sender>
+        <signal>clicked()</signal>
+        <receiver>TimedLogoutDlg</receiver>
+        <slot>reject()</slot>
+    </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kwin/workspace.cpp b/kwin/workspace.cpp
index fe008c399..bc8914f5b 100644
--- a/kwin/workspace.cpp
+++ b/kwin/workspace.cpp
@@ -59,6 +59,17 @@ KSelectionOwner* kompmgr_selection;
 
 bool allowKompmgrRestart = TRUE;
 
+bool supportsCompMgr()
+{
+    int i;
+
+    bool damageExt = XQueryExtension(qt_xdisplay(), "DAMAGE", &i, &i, &i);
+    bool compositeExt = XQueryExtension(qt_xdisplay(), "Composite", &i, &i, &i);
+    bool xfixesExt = XQueryExtension(qt_xdisplay(), "XFIXES", &i, &i, &i);
+
+    return damageExt && compositeExt && xfixesExt;
+}
+
 // Rikkus: This class is too complex. It needs splitting further.
 // It's a nightmare to understand, especially with so few comments :(
 
@@ -200,6 +211,9 @@ Workspace::Workspace( bool restore )
     connect( kapp->desktop(), TQT_SIGNAL( resized( int )), TQT_SLOT( desktopResized()));
 #endif
 
+    if (!supportsCompMgr())
+        options->useTranslucency = false;
+
     // start kompmgr - i wanted to put this into main.cpp, but that would prevent dcop support, as long as Application was no dcop_object
     if (options->useTranslucency)
         {
diff --git a/kxkb/kcmlayout.cpp b/kxkb/kcmlayout.cpp
index 502bf7972..7af7ae691 100644
--- a/kxkb/kcmlayout.cpp
+++ b/kxkb/kcmlayout.cpp
@@ -352,6 +352,9 @@ void LayoutConfig::add()
     // Create a copy of the sel widget, as one might add the same layout more
     // than one time, with different variants.
     TQListViewItem* toadd = copyLVI(sel, widget->listLayoutsDst);
+    
+    // Turn on "Include Latin layout" for new language by default (bnc:204402)
+    toadd->setText(LAYOUT_COLUMN_INCLUDE, "us");
 
     widget->listLayoutsDst->insertItem(toadd);
     if( widget->listLayoutsDst->childCount() > 1 )
diff --git a/nsplugins/nspluginloader.cpp b/nsplugins/nspluginloader.cpp
index e9c502169..3824334c0 100644
--- a/nsplugins/nspluginloader.cpp
+++ b/nsplugins/nspluginloader.cpp
@@ -326,7 +326,7 @@ TQString NSPluginLoader::lookup(const TQString &mimeType)
 }
 
 
-bool NSPluginLoader::loadViewer()
+bool NSPluginLoader::loadViewer(const TQString &mimeType)
 {
    kdDebug() << "NSPluginLoader::loadViewer" << endl;
 
@@ -350,7 +350,7 @@ bool NSPluginLoader::loadViewer()
    }
 
    // find the external artsdsp process
-   if( _useArtsdsp ) {
+   if( _useArtsdsp && mimeType != "application/pdf" ) {
        kdDebug() << "trying to use artsdsp" << endl;
        TQString artsdsp = KGlobal::dirs()->findExe("artsdsp");
        if (!artsdsp)
@@ -464,7 +464,7 @@ NSPluginInstance *NSPluginLoader::newInstance(TQWidget *parent, TQString url,
    if ( !_viewer )
    {
       // load plugin viewer process
-      loadViewer();
+      loadViewer(mimeType);
 
       if ( !_viewer )
       {
diff --git a/nsplugins/nspluginloader.h b/nsplugins/nspluginloader.h
index 6c2fe83c0..1748bb504 100644
--- a/nsplugins/nspluginloader.h
+++ b/nsplugins/nspluginloader.h
@@ -101,7 +101,7 @@ protected:
   TQString lookup(const TQString &mimeType);
   TQString lookupMimeType(const TQString &url);
 
-  bool loadViewer();
+  bool loadViewer(const TQString &mimeType);
   void unloadViewer();
 
 protected slots:
diff --git a/nsplugins/pluginscan.cpp b/nsplugins/pluginscan.cpp
index 82a5defb2..6914deb93 100644
--- a/nsplugins/pluginscan.cpp
+++ b/nsplugins/pluginscan.cpp
@@ -470,7 +470,7 @@ void writeServicesFile( TQStringList mimeTypes )
         ts << "Icon=netscape" << endl;
         ts << "Comment=" << i18n("Netscape plugin viewer") << endl;
         ts << "X-KDE-Library=libnsplugin" << endl;
-        ts << "InitialPreference=0" << endl;
+        ts << "InitialPreference=7" << endl;
         ts << "ServiceTypes=KParts/ReadOnlyPart,Browser/View" << endl;
         ts << "X-KDE-BrowserView-PluginsInfo=nsplugins/pluginsinfo" << endl;
 
-- 
cgit v1.2.3

