File kdm-make_it_cool.diff of Package kdebase3

Index: kdm/kfrontend/kdm_greet.c
===================================================================
--- kdm/kfrontend/kdm_greet.c.orig
+++ kdm/kfrontend/kdm_greet.c
@@ -44,8 +44,8 @@ Foundation, Inc., 51 Franklin Street, Fi
 # 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
 
Index: kdm/kfrontend/themer/kdmrect.h
===================================================================
--- kdm/kfrontend/themer/kdmrect.h.orig
+++ kdm/kfrontend/themer/kdmrect.h
@@ -36,6 +36,7 @@ class KdmRect : public KdmItem {
 
 public:
 	KdmRect( KdmItem *parent, const QDomNode &node, const char *name = 0 );
+	KdmRect( QWidget *parent, const QDomNode &node, const char *name = 0 );
 
 protected:
 	// draw the rect
@@ -54,8 +55,9 @@ protected:
 		bool hasBorder;
 	} rect;
 
-//	virtual void setWidget( QWidget *widget );
+	virtual void setWidget( QWidget *widget );
 //	virtual void setLayoutItem( QLayoutItem *item );
+	void init( const QDomNode &node, const char *name );
 
 private:
 	void setAttribs( QWidget *widget );
Index: kdm/kfrontend/themer/kdmitem.h
===================================================================
--- kdm/kfrontend/themer/kdmitem.h.orig
+++ kdm/kfrontend/themer/kdmitem.h
@@ -90,6 +90,8 @@ public:
 	 * Item constructor and destructor
 	 */
 	KdmItem( KdmItem *parent, const QDomNode &node = QDomNode(), const char *name = 0 );
+	KdmItem( QWidget *parent, const QDomNode &node = QDomNode(), const char *name = 0 ); // for the root
+
 	virtual ~KdmItem();
 
 	/**
@@ -151,6 +153,7 @@ public:
 
 	KdmItem *findNode( const QString &id ) const;
 	virtual void setWidget( QWidget *widget );
+	QWidget *widget() const { return myWidget; }
 	virtual void setLayoutItem( QLayoutItem *item );
 
 	virtual void hide( bool force = false );
@@ -160,6 +163,9 @@ public:
 	bool isExplicitlyHidden() const { return isShown == ExplicitlyHidden; }
 	QRect rect() const { return area; }
 
+	QWidget *parentWidget() const;
+	QString getId() const { return id; }
+
 signals:
 	void needUpdate( int x, int y, int w, int h );
 	void activated( const QString &id );
@@ -237,6 +243,7 @@ protected:
 	void parseColor( const QString &, QColor & );
 
 	void inheritFromButton( KdmItem *button );
+	void init( const QDomNode &node = QDomNode(), const char *name = 0 );
 
 	QString itemType, id;
 	QValueList<KdmItem *> m_children;
Index: kdm/kfrontend/themer/kdmpixmap.h
===================================================================
--- kdm/kfrontend/themer/kdmpixmap.h.orig
+++ kdm/kfrontend/themer/kdmpixmap.h
@@ -61,9 +61,10 @@ protected:
 	} pixmap;
 
 private:
-	// Method to load the pixmap given by the theme
-	void loadPixmap( const QString &fileName, QPixmap &p, QString &path );
+	// Method to load the pixmap path given by the theme
+	QString fullPath( const QString &fileName );
 	void renderSvg( PixmapStruct::PixmapClass *pClass, const QRect &area );
+	void loadPixmap( PixmapStruct::PixmapClass *pClass );
 };
 
 #endif
Index: kdm/kfrontend/themer/kdmlabel.h
===================================================================
--- kdm/kfrontend/themer/kdmlabel.h.orig
+++ kdm/kfrontend/themer/kdmlabel.h
@@ -67,6 +67,7 @@ protected:
 
 public slots:
 	void update();
+	void slotAccel();
 
 private:
 	/* Method to lookup the caption associated with an item */
@@ -76,6 +77,10 @@ private:
 	QString lookupText( const QString &t );
 
 	QString cText;
+	int cAccel;
+	QAccel *myAccel;
+
+	void setTextInt(const QString &);
 };
 
 #endif
Index: kdm/kfrontend/themer/kdmthemer.cpp
===================================================================
--- kdm/kfrontend/themer/kdmthemer.cpp.orig
+++ kdm/kfrontend/themer/kdmthemer.cpp
@@ -36,11 +36,13 @@
 
 #include <qfile.h>
 #include <qfileinfo.h>
-//#include <qtimer.h>		// animation timer - TODO
+#include <qtimer.h>		// animation timer - TODO
 #include <qobjectlist.h>
 #include <qpainter.h>
 #include <qwidget.h>
 #include <qregion.h>
+#include <qlineedit.h>
+#include <qapplication.h>
 
 #include <unistd.h>
 
@@ -72,7 +74,8 @@ KdmThemer::KdmThemer( const QString &_fi
 		return;
 	}
 	// Set the root (screen) item
-	rootItem = new KdmRect( 0, QDomNode(), "kdm root" );
+	rootItem = new KdmRect( parent, QDomNode(), "kdm root" );
+
 	connect( rootItem, SIGNAL(needUpdate( int, int, int, int )),
 	         widget(), SLOT(update( int, int, int, int )) );
 
@@ -82,6 +85,9 @@ KdmThemer::KdmThemer( const QString &_fi
 	generateItems( rootItem );
 
 	connect( rootItem, SIGNAL(activated( const QString & )), SIGNAL(activated( const QString & )) );
+	connect( rootItem, SIGNAL(activated( const QString & )), SLOT(slotActivated( const QString & )) );
+
+	QTimer::singleShot(800, this, SLOT(slotPaintRoot()));
 
 /*	*TODO*
 	// Animation timer
@@ -151,7 +157,7 @@ KdmThemer::widgetEvent( QEvent *e )
 	case QEvent::Paint:
 		{
 			QRect paintRect = static_cast<QPaintEvent *>(e)->rect();
-			kdDebug() << "paint on: " << paintRect << endl;
+			kdDebug() << timestamp() << " paint on: " << paintRect << endl;
 
 			if (!backBuffer)
 				backBuffer = new QPixmap( widget()->size() );
@@ -195,7 +201,7 @@ KdmThemer::generateItems( KdmItem *paren
 
 		// 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 *paren
 		if (tagName == "item") {
 			if (!willDisplay( subnode ))
 				continue;
+			QString 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
 			QString type = el.attribute( "type" );
 
@@ -225,13 +238,11 @@ KdmThemer::generateItems( KdmItem *paren
 				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 QDomN
 #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( QObject *obj )
 	const QObjectList *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++;
 		QObjectListIterator it( *wlist );
@@ -323,7 +339,46 @@ KdmThemer::showStructure( QObject *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 QString &id )
+{
+  QString 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();
+  QLineEdit *le = (QLineEdit*)item->widget()->qt_cast("QLineEdit");
+  if (le)
+    le->selectAll();
+}
+
+void
+KdmThemer::slotPaintRoot()
+{
+  KdmItem *back_item = findNode("background");
+  if (!back_item)
+    return;
+
+  QRect screen = QApplication::desktop()->screenGeometry(0);
+  QPixmap pm(screen.size());
+
+  QPainter painter( &pm, true );
+  back_item->paint( &painter, back_item->rect());
+  painter.end();
+
+  QApplication::desktop()->screen()->setErasePixmap(pm);
+  QApplication::desktop()->screen()->erase();
 }
 
 #include "kdmthemer.moc"
Index: kdm/kfrontend/themer/kdmthemer.h
===================================================================
--- kdm/kfrontend/themer/kdmthemer.h.orig
+++ kdm/kfrontend/themer/kdmthemer.h
@@ -80,6 +80,10 @@ public:
 signals:
 	void activated( const QString &id );
 
+protected slots:
+	void slotActivated( const QString &id );
+	void slotPaintRoot();
+
 private:
 	/*
 	 * Our display mode (e.g. console, remote, ...)
Index: kdm/kfrontend/themer/kdmlayout.cpp
===================================================================
--- kdm/kfrontend/themer/kdmlayout.cpp.orig
+++ 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 QD
 void
 KdmLayoutFixed::update( const QRect &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 QRect &paren
 				childrenRect.setTop( childrenRect.top() + height + box.spacing );
 			} else {
 				QRect 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 QRect &paren
 				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;
Index: kdm/kfrontend/themer/kdmrect.cpp
===================================================================
--- kdm/kfrontend/themer/kdmrect.cpp.orig
+++ kdm/kfrontend/themer/kdmrect.cpp
@@ -33,6 +33,18 @@
 KdmRect::KdmRect( KdmItem *parent, const QDomNode &node, const char *name )
     : KdmItem( parent, node, name )
 {
+  init( node, name );
+}
+
+KdmRect::KdmRect( QWidget *parent, const QDomNode &node, const char *name )
+    : KdmItem( parent, node, name )
+{
+  init( node, name );
+}
+
+void
+KdmRect::init( const QDomNode &node, const char * )
+{
 	itemType = "rect";
 
 	// Set default values for rect (note: strings are already Null)
@@ -137,13 +149,6 @@ KdmRect::recursiveSetAttribs( QLayoutIte
 }
 
 void
-KdmRect::setWidget( QWidget *widget )
-{
-	KdmItem::setWidget( widget );
-	setAttribs( widget );
-}
-
-void
 KdmRect::setLayoutItem( QLayoutItem *item )
 {
 	KdmItem::setLayoutItem( item );
@@ -151,4 +156,17 @@ KdmRect::setLayoutItem( QLayoutItem *ite
 }
 */
 
+void
+KdmRect::setWidget( QWidget *widget )
+{
+        if ( rect.normal.color.isValid() && widget ) 
+        {
+     	     QPalette p = widget->palette();
+	     p.setColor( QPalette::Normal, QColorGroup::Text, rect.normal.color );
+	     widget->setPalette(p);
+	}
+	KdmItem::setWidget( widget );
+	//setAttribs( widget );
+}
+
 #include "kdmrect.moc"
Index: kdm/kfrontend/themer/kdmitem.cpp
===================================================================
--- kdm/kfrontend/themer/kdmitem.cpp.orig
+++ 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 <qwidget.h>
 #include <qlayout.h>
 #include <qimage.h>
-#ifdef DRAW_OUTLINE
-# include <qpainter.h>
-#endif
+#include <qpainter.h>
 
 KdmItem::KdmItem( KdmItem *parent, const QDomNode &node, const char *name )
     : QObject( parent, name )
@@ -48,6 +47,25 @@ KdmItem::KdmItem( KdmItem *parent, const
     , myLayoutItem( 0 )
     , buttonParent( 0 )
 {
+  init(node, name);
+}
+
+
+KdmItem::KdmItem( QWidget *parent, const QDomNode &node, const char *name )
+    : QObject( parent, name )
+    , boxManager( 0 )
+    , fixedManager( 0 )
+    , image( 0 )
+    , myWidget( 0 )
+    , myLayoutItem( 0 )
+    , buttonParent( 0 )
+{
+  init(node, name);
+}
+
+void
+KdmItem::init( const QDomNode &node, const char * )
+{
 	// Set default layout for every item
 	currentManager = MNone;
 	pos.x = pos.y = 0;
@@ -62,7 +80,7 @@ KdmItem::KdmItem( KdmItem *parent, const
 	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
 	id = tnode.toElement().attribute( "id", QString::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( QWidget *widget )
 	if (frame)
 		frame->setFrameStyle( QFrame::NoFrame );
 
-	myWidget->setGeometry(area);
+	setGeometry(area, true);
 
 	connect( myWidget, SIGNAL(destroyed()), SLOT(widgetGone()) );
 }
@@ -236,15 +254,21 @@ KdmItem::setGeometry( const QRect &newGe
 
 	area = newGeometry;
 
-	if (myWidget)
-		myWidget->setGeometry( newGeometry );
+	if (myWidget) {
+            QRect 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( QPainter *p, const QRect
 	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" ) ) {
+                QPixmap copy( myWidget->size() );
+                kdDebug() <<  myWidget->geometry() << " " << area << " " << myWidget->size() << endl;
+                bitBlt( &copy, QPoint( 0, 0), p->device(), myWidget->geometry(), Qt::CopyROP );
+                myWidget->setPaletteBackgroundPixmap( copy );
+            }
+            return;
+        }
 
 	if (area.intersects( rect )) {
 		QRect contentsRect = area.intersect( rect );
@@ -280,6 +312,8 @@ KdmItem::paint( QPainter *p, const QRect
 	QValueList<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 QRect &par
 	    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 QRect &par
 				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 QRect &par
 	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 QRect &par
 	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 QRect &par
 			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 QDomNode
 	currentManager = MFixed;
 }
 
+QWidget *
+KdmItem::parentWidget() const
+{
+  if (myWidget)
+    return myWidget;
+  if (!this->parent())
+    return 0;
+
+  if (parent()->qt_cast("QWidget"))
+    return (QWidget*)parent();
+  return ((KdmItem*)parent())->parentWidget();
+}
+
 #include "kdmitem.moc"
Index: kdm/kfrontend/themer/kdmpixmap.cpp
===================================================================
--- kdm/kfrontend/themer/kdmpixmap.cpp.orig
+++ 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 <qpainter.h>
 #include <qpixmap.h>
@@ -58,21 +60,28 @@ KdmPixmap::KdmPixmap( KdmItem *parent, c
 		QString 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 QRect &new
 }
 
 
-void
-KdmPixmap::loadPixmap( const QString &fileName, QPixmap &map, QString &fullName )
+QString
+KdmPixmap::fullPath( const QString &fileName)
 {
-	if (fileName.isEmpty())
-		return;
+        if (fileName.isEmpty())
+		return QString::null;
 
-	fullName = fileName;
+	QString fullName = fileName;
 	if (fullName.at( 0 ) != '/')
 		fullName = baseDir() + "/" + fileName;
-
-	if (!fullName.endsWith( ".svg" ))	// we delay it for svgs
-		if (!map.load( fullName ))
-			fullName = QString::null;
+	return fullName;
 }
 
 void
@@ -140,6 +146,25 @@ KdmPixmap::renderSvg( PixmapStruct::Pixm
 }
 
 void
+KdmPixmap::loadPixmap( PixmapStruct::PixmapClass *pClass )
+{
+  QString fullpath = pClass->fullpath;
+
+  kdDebug() << timestamp() << " load " << fullpath << endl;
+  int index = fullpath.findRev('.');
+  QString ext = fullpath.right(fullpath.length() - index);
+  fullpath = fullpath.left(index);
+  kdDebug() << timestamp() << " ext " << ext << " " << fullpath << endl;
+  QString testpath = QString("-%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( QPainter *p, const QRect &r )
 {
 	// choose the correct pixmap class
@@ -149,12 +174,20 @@ KdmPixmap::drawContents( QPainter *p, co
 	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( QPainter *p, co
 
 
 	if (pClass->readyPixmap.isNull()) {
-		QImage scaledImage;
+	  
+		bool haveTint = pClass->tint.rgb() != 0xFFFFFF;
+		bool haveAlpha = pClass->alpha < 1.0;
 
+		QImage 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";
 				QImage 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( QPainter *p, co
 
 		}
 
-		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 );
 }
 
Index: kdm/kfrontend/themer/kdmlabel.cpp
===================================================================
--- kdm/kfrontend/themer/kdmlabel.cpp.orig
+++ 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 <qpainter.h>
 #include <qfontmetrics.h>
 #include <qtimer.h>
+#include <qaccel.h>
 
 #include <unistd.h>
 #include <sys/utsname.h>
@@ -39,7 +42,7 @@
 #endif
 
 KdmLabel::KdmLabel( KdmItem *parent, const QDomNode &node, const char *name )
-    : KdmItem( parent, node, name )
+       : KdmItem( parent, node, name ), myAccel(0)
 {
 	itemType = "label";
 
@@ -92,21 +95,46 @@ KdmLabel::KdmLabel( KdmItem *parent, con
 		}
 	}
 
-	// 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 QTimer( this );
 		timer->start( 1000 );
 		connect( timer, SIGNAL(timeout()), SLOT(update()) );
 	}
-	cText = lookupText( label.text );
+	setTextInt( lookupText( label.text ) );
+}
+
+void
+KdmLabel::setTextInt( const QString &txt)
+{
+  // TODO: catch &&
+        cText = txt;
+	cAccel = txt.find('&');
+	delete myAccel;
+	myAccel = 0;
+	if (cAccel != -1) {
+	  cText.remove('&');
+	  myAccel = new QAccel(parentWidget());
+	  myAccel->insertItem(ALT + UNICODE_ACCEL + cText.at(cAccel).lower().unicode());
+	  connect(myAccel, SIGNAL(activated(int)), SLOT(slotAccel()));
+	}
+}
+
+void
+KdmLabel::slotAccel()
+{
+  if (buttonParent)
+    emit activated(buttonParent->getId());
+  else
+    emit activated(id);
 }
 
 void
 KdmLabel::setText( const QString &txt )
 {
 	label.text = txt;
-	update();
+	setTextInt( lookupText( label.text ) );
 }
 
 QSize
@@ -139,7 +167,23 @@ KdmLabel::drawContents( QPainter *p, con
 	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) ) {
+	  QString left = cText.left(cAccel);
+	  QString right = cText.mid(cAccel + 1);
+	  p->drawText( area, AlignLeft | SingleLine, left );
+	  QRect tarea = area;
+	  QFontMetrics fm(l->font);
+	  tarea.rLeft() += fm.width(left);
+	  QFont f(l->font);
+	  f.setUnderline(true);
+	  p->setFont ( f );
+	  p->drawText( tarea, AlignLeft | SingleLine, QString(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()
 {
 	QString text = lookupText( label.text );
 	if (text != cText) {
-		cText = text;
+	        setTextInt(text);
 		needUpdate();
 	}
 }
@@ -167,22 +211,23 @@ KdmLabel::update()
 static const struct {
 	const char *type, *text;
 } stocks[] = {
-	{ "language",           I18N_NOOP("Language") },
-	{ "session",            I18N_NOOP("Session Type") },
-	{ "system",             I18N_NOOP("Menu") },	// i18n("Actions");
-	{ "disconnect",         I18N_NOOP("Disconnect") },
-	{ "quit",               I18N_NOOP("Quit") },
-	{ "halt",               I18N_NOOP("Power off") },
-	{ "suspend",            I18N_NOOP("Suspend") },
-	{ "reboot",             I18N_NOOP("Reboot") },
+	{ "language",           I18N_NOOP("&Language") },
+	{ "session",            I18N_NOOP("Session &Type") },
+	{ "system",             I18N_NOOP("&System") }, // i18n("Actions");
+	{ "disconnect",         I18N_NOOP("&Disconnect") },
+	{ "quit",               I18N_NOOP("&Quit") },
+	{ "halt",               I18N_NOOP("Power O&ff") },
+	{ "suspend",            I18N_NOOP("S&uspend") },
+	{ "reboot",             I18N_NOOP("&Reboot") },
 	{ "chooser",            I18N_NOOP("XDMCP Chooser") },
 	{ "config",             I18N_NOOP("Configure") },
-	{ "caps-lock-warning",  I18N_NOOP("You have got caps lock on.") },
-	{ "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:") },
-	{ "login",              I18N_NOOP("Login") }
+	{ "caps-lock-warning",  I18N_NOOP("Caps Lock is enabled.") },
+	{ "timed-label",        I18N_NOOP("User %s will log in 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("L&ogin") }
 };
 
 QString
@@ -195,7 +240,7 @@ KdmLabel::lookupStock( const QString &st
 		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 +250,6 @@ KdmLabel::lookupText( const QString &t )
 	QString text = t;
 
 	text.replace( '_', '&' );
-//	text.remove( '_' ); // FIXME add key accels, remove underscores for now
 
 	QMap<QChar,QString> m;
 	struct utsname uts;
Index: kdm/kfrontend/kdmconfig.h
===================================================================
--- kdm/kfrontend/kdmconfig.h.orig
+++ kdm/kfrontend/kdmconfig.h
@@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fi
 #include <qstring.h>
 #include <qstringlist.h>
 #include <qfont.h>
+#include <sys/time.h>
 
 extern QString _stsFile;
 extern bool _isLocal;
@@ -46,6 +47,19 @@ CONF_GREET_CPP_DECLS
 struct dpySpec;
 void decodeSess( dpySpec *sess, QString &user, QString &loc );
 
+extern struct timeval st;
+
+inline QString timestamp() {
+	struct timeval nst;
+	gettimeofday(&nst, 0);
+	if (!st.tv_sec)
+		gettimeofday(&st, 0);
+
+	QString 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 );
Index: kdm/kfrontend/kgreeter.h
===================================================================
--- kdm/kfrontend/kgreeter.h.orig
+++ kdm/kfrontend/kgreeter.h
@@ -73,9 +73,10 @@ class KGreeter : public KGDialog, public
 	void slotUserEntered();
 
   protected:
+        void readFacesList();
 	void installUserList();
 	void insertUser( const QImage &, const QString &, struct passwd * );
-	void insertUsers();
+	void insertUsers( int limit = -1);
 	void putSession( const QString &, const QString &, bool, const char * );
 	void insertSessions();
 	virtual void pluginSetup();
@@ -87,10 +88,13 @@ class KGreeter : public KGDialog, public
 	QStringList *userList;
 	QPopupMenu *sessMenu;
 	QValueVector<SessType> sessionTypes;
+        QStringList randomFaces;
+        QMap<QString, QString> randomFacesMap;
 	int nNormals, nSpecials;
 	int curPrev, curSel;
 	bool prevValid;
 	bool needLoad;
+        bool themed;
 
 	static int curPlugin;
 	static PluginList pluginList;
Index: kdm/kfrontend/kgdialog.cpp
===================================================================
--- kdm/kfrontend/kgdialog.cpp.orig
+++ kdm/kfrontend/kgdialog.cpp
@@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fi
 #include "kdm_greet.h"
 
 #include <klocale.h>
+#include <kiconloader.h>
 
 #include <qaccel.h>
 #include <qlayout.h>
@@ -58,7 +59,7 @@ KGDialog::completeMenu()
 #ifdef HAVE_VTS
 	if (_isLocal) {
 		dpyMenu = new QPopupMenu( this );
-		int id = inserten( i18n("Sw&itch User"), ALT+Key_I, dpyMenu );
+		int id = inserten( i18n("Sw&itch User"), CTRL + Key_I, dpyMenu );
 		connect( dpyMenu, SIGNAL(activated( int )),
 		         SLOT(slotDisplaySelected( int )) );
 		connect( dpyMenu, SIGNAL(aboutToShow()),
@@ -71,7 +72,7 @@ KGDialog::completeMenu()
 
 	if (_allowClose)
 		inserten( _isLocal ? i18n("R&estart X Server") : i18n("Clos&e Connection"),
-		          ALT+Key_E, SLOT(slotExit()) );
+		          0, SLOT(slotExit()) );
 
 #ifdef XDMCP
 	if (_isLocal && _loginMode != _switchIf) {
@@ -81,10 +82,11 @@ KGDialog::completeMenu()
 #endif
 
 	if (_hasConsole)
-		inserten( i18n("Co&nsole Login"), ALT+Key_N, SLOT(slotConsole()) );
+		inserten( i18n("Co&nsole Login"), CTRL+Key_N, SLOT(slotConsole()) );
 
 	if (_allowShutdown != SHUT_NONE) {
-		inserten( i18n("&Shutdown..."), ALT+Key_S, SLOT(slotShutdown( int )) );
+                ensureMenu();
+                optMenu->insertItem(SmallIconSet( "exit" ), i18n("&Shutdown..."), this, SLOT(slotShutdown(int)), CTRL+Key_S );
 		QAccel *accel = new QAccel( this );
 		accel->insertItem( ALT+CTRL+Key_Delete );
 		connect( accel, SIGNAL(activated( int )), SLOT(slotShutdown( int )) );
Index: kdm/kfrontend/kdmconfig.cpp
===================================================================
--- kdm/kfrontend/kdmconfig.cpp.orig
+++ kdm/kfrontend/kdmconfig.cpp
@@ -33,6 +33,8 @@ Foundation, Inc., 51 Franklin Street, Fi
 #include <unistd.h>
 #include <sys/utsname.h>
 
+struct timeval st = {0, 0};
+
 CONF_GREET_DEFS
 
 QString _stsFile;
Index: kdm/kfrontend/kgapp.cpp
===================================================================
--- kdm/kfrontend/kgapp.cpp.orig
+++ kdm/kfrontend/kgapp.cpp
@@ -36,6 +36,8 @@ Foundation, Inc., 51 Franklin Street, Fi
 #include <kcrash.h>
 #include <kstandarddirs.h>
 #include <ksimpleconfig.h>
+#include <klocale.h>
+#include <kdebug.h>
 
 #include <qtimer.h>
 #include <qcursor.h>
@@ -130,6 +132,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 );
@@ -166,6 +169,7 @@ kg_main( const char *argv0 )
 
 	GSendInt( G_Ready );
 
+	kdDebug() << timestamp() << " main1" << endl;	
 	setCursor( dpy, app.desktop()->winId(), XC_left_ptr );
 
 	for (;;) {
@@ -206,6 +210,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;
Index: kdm/kfrontend/kgreeter.cpp
===================================================================
--- kdm/kfrontend/kgreeter.cpp.orig
+++ kdm/kfrontend/kgreeter.cpp
@@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fi
 #include <klistview.h>
 #include <ksimpleconfig.h>
 #include <kstringhandler.h>
+#include <kdebug.h>
 
 #undef Unsorted // x headers suck - make qdir.h work with --enable-final
 #include <qdir.h>
@@ -46,6 +47,7 @@ Foundation, Inc., 51 Franklin Street, Fi
 #include <qmemarray.h>
 #include <qimage.h>
 #include <qmovie.h>
+#include <qpainter.h>
 #include <qpopupmenu.h>
 #include <qtimer.h>
 #include <qheader.h>
@@ -63,27 +65,46 @@ Foundation, Inc., 51 Franklin Street, Fi
 #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( QWidget *parent = 0, const char *name = 0 )
+        UserListView( bool _them, QWidget *parent = 0, const char *name = 0 )
 		: KListView( parent, name )
-		, cachedSizeHint( -1, 0 )
+		, themed(_them), cachedSizeHint( -1, 0 )
 	{
 		setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Ignored );
 		header()->hide();
 		addColumn( QString::null );
 		setColumnAlignment( 0, AlignVCenter );
 		setResizeMode( QListView::LastColumn );
+		if (themed) {
+		  setBackgroundMode( Qt::NoBackground );
+		  viewport()->setBackgroundMode( Qt::NoBackground );
+		  setFrameStyle( QFrame::NoFrame );
+		}
 	}
 
+        bool themed;
 	mutable QSize cachedSizeHint;
 
-  protected:
+        int sumHeight() const 
+  {
+        int sum = 0;
+        for (QListViewItem *itm = firstChild(); itm; itm = itm->nextSibling()) {
+            sum += itm->height();
+        }
+        return sum;
+    }
+public:
 	virtual QSize sizeHint() const
 	{
+	  if (themed)
+            return KListView::sizeHint();
+
 		if (!cachedSizeHint.isValid()) {
 			constPolish();
 			uint maxw = 0;
@@ -98,8 +119,23 @@ class UserListView : public KListView {
 		}
 		return cachedSizeHint;
 	}
-};
+    virtual void paintEmptyArea ( QPainter * p, const QRect & rect )
+    {
+      if (!themed)
+        return KListView::paintEmptyArea(p, rect );
+
+        const QPixmap *pm = paletteBackgroundPixmap();
+        if (!pm || pm->isNull())
+            return;
+
+        kdDebug() << "paintEmpty " << rect << endl;
+        QRect devRect = p->xForm( rect );
+        kdDebug() << "paintEmpty2 " << devRect << endl;
+        p->drawPixmap(0, 0, *pm, devRect.left(), devRect.top() );
+    }
 
+    QPixmap background;
+};
 
 int KGreeter::curPlugin = -1;
 PluginList KGreeter::pluginList;
@@ -115,12 +151,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, SIGNAL(clicked( QListViewItem * )),
 		         SLOT(slotUserClicked( QListViewItem * )) );
 		connect( userView, SIGNAL(doubleClicked( QListViewItem * )),
@@ -128,10 +166,8 @@ KGreeter::KGreeter( bool framed )
 	}
 	if (_userCompletion)
 		userList = new QStringList;
-	if (userView || userList)
-		insertUsers();
 
-	sessMenu = new QPopupMenu( this );
+        sessMenu = new QPopupMenu( this );
 	connect( sessMenu, SIGNAL(activated( int )),
 	         SLOT(slotSessionSelected( int )) );
 	insertSessions();
@@ -150,6 +186,33 @@ KGreeter::~KGreeter()
 	delete stsFile;
 }
 
+void KGreeter::readFacesList()
+{
+    FILE *f = fopen( QFile::encodeName( _faceDir + "/.randomlist" ), "rt" );
+    if ( !f )
+        return;
+    QTextIStream is( f );
+    while ( !is.eof() )
+    {
+        QString line = is.readLine().simplifyWhiteSpace();
+        if ( line.isEmpty() )
+            continue;
+        QString icon;
+        int index = line.find( ' ' );
+        if ( index > 0 ) {
+            icon = line.left( index );
+            line = line.mid( index );
+        } else {
+            icon = line;
+            line = QString::null;
+        }
+        randomFaces.push_back( icon );
+        QStringList list = QStringList::split( ' ', line );
+        for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
+            randomFacesMap[*it] = icon;
+    }
+}
+
 class UserListViewItem : public KListViewItem {
   public:
 	UserListViewItem( UserListView *parent, const QString &text,
@@ -163,6 +226,14 @@ class UserListViewItem : public KListVie
 		parent->cachedSizeHint.setWidth( -1 );
 	}
 
+        virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment)
+    {
+      if (((UserListView*)listView())->themed)
+        QListViewItem::paintCell(p, cg, column, width, alignment);
+      else
+	KListViewItem::paintCell(p, cg, column, width, alignment);
+    }
+
 	QString login;
 };
 
@@ -224,10 +295,23 @@ KGreeter::insertUser( const QImage &defa
 		QSize ns( 48, 48 );
 		if (p.size() != ns)
 			p = p.convertDepth( 32 ).smoothScale( ns, QImage::ScaleMin );
-		goto gotit;
+		break;
 	} while (--nd >= 0);
-	p = default_pix;
-  gotit:
+
+        if ( p.isNull() && randomFaces.count() ) {
+            QString randomFace = randomFacesMap[username];
+            if ( randomFace.isNull() ) {
+                QStringList::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;
+
 	QString realname = KStringHandler::from8Bit( ps->pw_gecos );
 	realname.truncate( realname.find( ',' ) );
 	if (realname.isEmpty() || realname == username)
@@ -278,7 +362,7 @@ UserList::UserList( char **in )
 }
 
 void
-KGreeter::insertUsers()
+KGreeter::insertUsers(int limit_users)
 {
 	struct passwd *ps;
 
@@ -305,6 +389,8 @@ KGreeter::insertUsers()
 	if (_showUsers == SHOW_ALL) {
 		UserList noUsers( _noUsers );
 		QDict<int> dupes( 1000 );
+                QStringList toinsert;
+                int count = 0;
 		for (setpwent(); (ps = getpwent()) != 0;) {
 			if (*ps->pw_dir && *ps->pw_shell &&
 			    (ps->pw_uid >= (unsigned)_lowUserId ||
@@ -316,10 +402,53 @@ KGreeter::insertUsers()
 				QString username( QFile::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 = QStringList();
+                    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 ))
+                        {
+                            QString username( QFile::decodeName( ent->ut_user ) );
+                            if (!dupes.find( username )) {
+                                dupes.insert( username, (int *)-1 );
+                                toinsert.append( username );
+                                count++;
+                            }
+                        }
+
+
+                    }
+                    endutxent();
+                }
+
+                for ( QStringList::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( QFile::encodeName( *it ) );
+                    if ( ps )
+                        insertUser( default_pix, *it, ps );
+                }
 	} else {
 		UserList users( _users );
 		if (users.hasGroups()) {
@@ -721,21 +850,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
@@ -829,6 +961,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" );
@@ -854,37 +989,31 @@ KThemedGreeter::KThemedGreeter()
 	if ((itm = themer->findNode( "session_button" ))) {
 		if (sessMenu->count() <= 1)
 			itm->hide( true );
-		else {
-			session_button = itm;
-			QAccel *accel = new QAccel( this );
-			accel->insertItem( ALT+Key_T, 0 );
-			connect( accel, SIGNAL(activated( int )), SLOT(slotSessMenu()) );
-		}
+                else
+                    session_button = itm;
 	} else {
 		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
 
 	system_button = themer->findNode( "system_button" );
-	QAccel *accel = new QAccel( this );
-	accel->insertItem( ALT+Key_M, 0 );
-	connect( accel, SIGNAL(activated( int )), SLOT(slotActionMenu()) );
 
 	pluginSetup();
 
+
 	verify->start();
 }
 
@@ -902,8 +1031,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();
@@ -919,12 +1048,17 @@ KThemedGreeter::verifyFailed()
 {
 //	goButton->setEnabled( false );
 	inherited::verifyFailed();
+	if (userView)
+		userView->setEnabled(false);
 }
 
 void
 KThemedGreeter::verifyRetry()
 {
 //	goButton->setEnabled( true );
+        if (userView)
+                userView->setEnabled(true);
+
 }
 
 QString KThemedGreeter::timedUser = QString::null;
openSUSE Build Service is sponsored by