[Frugalware-git] kde359: kdebase-3.5.9-2-i686

crazy crazy at frugalware.org
Sat Feb 23 05:11:32 CET 2008


Git-Url: http://git.frugalware.org/gitweb/gitweb.cgi?p=kde359.git;a=commitdiff;h=fe5625818a6ced7523e1537b61e639aa68286677

commit fe5625818a6ced7523e1537b61e639aa68286677
Author: crazy <crazy at frugalware.org>
Date:   Sat Feb 23 04:58:36 2008 +0100

kdebase-3.5.9-2-i686
* release bump
* added kdm patch stolen from suse :)
* don't remove kdmrc , just move it around

diff --git a/source/kde/kdebase/FrugalBuild b/source/kde/kdebase/FrugalBuild
index 0493732..011fe7b 100644
--- a/source/kde/kdebase/FrugalBuild
+++ b/source/kde/kdebase/FrugalBuild
@@ -3,7 +3,7 @@

pkgname=kdebase
pkgver=3.5.9
-pkgrel=1
+pkgrel=2
pkgdesc="KDE Base Programs."
depends=('libxcomposite' 'libxscrnsaver' 'kdelibs>=3.5.9' 'libraw1394' 'hal>=0.5.7.1-3' 'mtools' 'libxdamage' \
'xscreensaver-data' 'bdftopcf' 'lmsensors' 'libxxf86misc' 'libfontenc' \
@@ -32,7 +32,8 @@ source=(${source[@]} \
clock.patch \
media_ntfs3g.patch \
kdebase-3.5.6-konsole_url.diff \
-	FS2618-mount-utf8.patch)
+	FS2618-mount-utf8.patch \
+	kdm-make_it_cool.diff)
## NOTE: if someone change fw-default-dejavu-font.patch its _NEED_ be in sync with
##       fw-default-dejavu-font.patch from kdelibs and both pkgs _NEED_ be recompiled!
##       DO NOT REMOVE or CHANGE fw-default-startkde.patch without permission from m8r!  - crazy -
@@ -66,7 +67,7 @@ build()
# Session file.
Ffile /etc/X11/sessions/kde.desktop
## remove files are in kde-frugalware package
-	Frm usr/share/config/kdm/kdmrc
+	Fmv usr/share/config/kdm/kdmrc usr/share/config/kdm/kdmrc-${pkgver}
Frm usr/share/config/kdm/backgroundrc
Frm usr/share/config/klipperrc
Frm usr/share/apps/ksmserver/pics/shutdownkonq.png
@@ -93,5 +94,6 @@ sha1sums=('a6a19e0b26ed7a2b138a4a7594c8486e26610de8' \
'1233baad88df6a7a5347db7392a3afa7f21812fd' \
'afff70bdd816bfbff5fb3fd6e612c648ef901858' \
'82367166851f1f95037cf00e767bc76135371358' \
-          'e26edb86f227989f917a335c3b2a4f45bb9c48d4')
+          'e26edb86f227989f917a335c3b2a4f45bb9c48d4' \
+          '0bbf36c71b433a294029a36a80e916ad332eca50')
# optimization OK
diff --git a/source/kde/kdebase/kdm-make_it_cool.diff b/source/kde/kdebase/kdm-make_it_cool.diff
new file mode 100644
index 0000000..ea83095
--- /dev/null
+++ b/source/kde/kdebase/kdm-make_it_cool.diff
@@ -0,0 +1,1502 @@
+--- kfrontend/kdm_greet.c
++++ kdm/kfrontend/kdm_greet.c
+@@ -44,8 +44,8 @@
+ # include <sched.h>
+ #endif
+
++# include <X11/Xlib.h>
+ #if defined(HAVE_XTEST) || defined(HAVE_XKB)
+-# include <X11/Xlib.h>
+ # include <X11/keysym.h>
+ #endif
+
+--- kfrontend/themer/kdmrect.h
++++ kdm/kfrontend/themer/kdmrect.h
+@@ -36,6 +36,7 @@
+
+ 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 @@
+ 		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 );
+--- kfrontend/themer/kdmitem.h
++++ kdm/kfrontend/themer/kdmitem.h
+@@ -90,6 +90,8 @@
+ 	 * 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 @@
+
+ 	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 @@
+ 	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 @@
+ 	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;
+--- kfrontend/themer/kdmpixmap.h
++++ kdm/kfrontend/themer/kdmpixmap.h
+@@ -61,9 +61,10 @@
+ 	} 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
+--- kfrontend/themer/kdmlabel.h
++++ kdm/kfrontend/themer/kdmlabel.h
+@@ -67,6 +67,7 @@
+
+ public slots:
+ 	void update();
++	void slotAccel();
+
+ private:
+ 	/* Method to lookup the caption associated with an item */
+@@ -76,6 +77,10 @@
+ 	QString lookupText( const QString &t );
+
+ 	QString cText;
++	int cAccel;
++	QAccel *myAccel;
++
++	void setTextInt(const QString &);
+ };
+
+ #endif
+--- kfrontend/themer/kdmthemer.cpp
++++ 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 @@
+ 		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,7 +85,10 @@
+ 	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
+ 	QTimer *time = new QTimer( this );
+@@ -151,7 +157,7 @@
+ 	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 @@
+
+ 		// 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 @@
+ 		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 @@
+ 				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 @@
+ #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 @@
+ 	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 @@
+ 		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"
+--- kfrontend/themer/kdmthemer.h
++++ kdm/kfrontend/themer/kdmthemer.h
+@@ -80,6 +80,10 @@
+ signals:
+ 	void activated( const QString &id );
+
++protected slots:
++	void slotActivated( const QString &id );
++	void slotPaintRoot();
++
+ private:
+ 	/*
+ 	 * Our display mode (e.g. console, remote, ...)
+--- kfrontend/themer/kdmlayout.cpp
++++ 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 @@
+ 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 @@
+ 				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 @@
+ 				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;
+--- kfrontend/themer/kdmrect.cpp
++++ 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 @@
+ }
+
+ void
+-KdmRect::setWidget( QWidget *widget )
+-{
+-	KdmItem::setWidget( widget );
+-	setAttribs( widget );
+-}
+-
+-void
+ KdmRect::setLayoutItem( QLayoutItem *item )
+ {
+ 	KdmItem::setLayoutItem( item );
+@@ -151,4 +156,17 @@
+ }
+ */
+
++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"
+--- kfrontend/themer/kdmitem.cpp
++++ 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 @@
+     , 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 @@
+ 	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 @@
+ 	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 @@
+ 	if (frame)
+ 		frame->setFrameStyle( QFrame::NoFrame );
+
+-	myWidget->setGeometry(area);
++	setGeometry(area, true);
+
+ 	connect( myWidget, SIGNAL(destroyed()), SLOT(widgetGone()) );
+ }
+@@ -236,15 +254,21 @@
+
+ 	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 @@
+ 	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 @@
+ 	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 @@
+ 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 @@
+ 	    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 @@
+ 				return parentRect;
+ 			boxHint = boxManager->sizeHint();
+ 		}
+-		kdDebug() << " => boxHint " << boxHint << endl;
++		kdDebug() << timestamp() << " boxHint " << boxHint << endl;
+ 	}
+
+ 	if (pos.xType == DTpixel)
+@@ -380,25 +418,25 @@
+ 	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 @@
+ 	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 @@
+ 			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 @@
+ 	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"
+--- kfrontend/themer/kdmpixmap.cpp
++++ 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 @@
+ 		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 @@
+ }
+
+
+-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 @@
+ }
+
+ 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 @@
+ 	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,26 +209,38 @@
+
+
+ 	if (pClass->readyPixmap.isNull()) {
++
++		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();
++                        // enforce rgba values for the later
++                        scaledImage = scaledImage.convertDepth( 32 );
++                  }
++		  else
++		    pClass->readyPixmap = pClass->pixmap;
++		}
+
+-		bool haveTint = pClass->tint.rgb() != 0xFFFFFF;
+-		bool haveAlpha = pClass->alpha < 1.0;
+-
+ 		if (haveTint || haveAlpha) {
+ 			// blend image(pix) with the given tint
+
+@@ -220,9 +265,12 @@
+
+ 		}
+
+-		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 );
+ }
+
+--- kfrontend/themer/kdmlabel.cpp
++++ 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 @@
+ 		}
+ 	}
+
+-	// 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 @@
+ 	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 @@
+ {
+ 	QString text = lookupText( label.text );
+ 	if (text != cText) {
+-		cText = text;
++	        setTextInt(text);
+ 		needUpdate();
+ 	}
+ }
+@@ -167,22 +211,23 @@
+ 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 @@
+ 		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 @@
+ 	QString text = t;
+
+ 	text.replace( '_', '&' );
+-//	text.remove( '_' ); // FIXME add key accels, remove underscores for now
+
+ 	QMap<QChar,QString> m;
+ 	struct utsname uts;
+--- kfrontend/kdmconfig.h
++++ kdm/kfrontend/kdmconfig.h
+@@ -35,6 +35,7 @@
+ #include <qstring.h>
+ #include <qstringlist.h>
+ #include <qfont.h>
++#include <sys/time.h>
+
+ extern QString _stsFile;
+ extern bool _isLocal;
+@@ -46,6 +47,19 @@
+ 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 );
+--- kfrontend/kgreeter.h
++++ kdm/kfrontend/kgreeter.h
+@@ -73,9 +73,10 @@
+ 	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 @@
+ 	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;
+--- kfrontend/kgdialog.cpp
++++ kdm/kfrontend/kgdialog.cpp
+@@ -29,6 +29,7 @@
+ #include "kdm_greet.h"
+
+ #include <klocale.h>
++#include <kiconloader.h>
+
+ #include <qaccel.h>
+ #include <qlayout.h>
+@@ -58,7 +59,7 @@
+ #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 @@
+
+ 	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 @@
+ #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 )) );
+--- kfrontend/kdmconfig.cpp
++++ kdm/kfrontend/kdmconfig.cpp
+@@ -33,6 +33,8 @@
+ #include <unistd.h>
+ #include <sys/utsname.h>
+
++struct timeval st = {0, 0};
++
+ CONF_GREET_DEFS
+
+ QString _stsFile;
+--- kfrontend/kgapp.cpp
++++ kdm/kfrontend/kgapp.cpp
+@@ -36,6 +36,8 @@
+ #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 @@
+ 	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 @@
+
+ 	GSendInt( G_Ready );
+
++	kdDebug() << timestamp() << " main1" << endl;
+ 	setCursor( dpy, app.desktop()->winId(), XC_left_ptr );
+
+ 	for (;;) {
+@@ -206,6 +210,7 @@
+ 			if (_useTheme && !_theme.isEmpty()) {
+ 				KThemedGreeter *tgrt;
+ 				dialog = tgrt = new KThemedGreeter;
++				kdDebug() << timestamp() << " themed" << endl;
+ 				if (!tgrt->isOK()) {
+ 					delete tgrt;
+ 					dialog = new KStdGreeter;
+--- kfrontend/kgreeter.cpp
++++ kdm/kfrontend/kgreeter.cpp
+@@ -38,14 +38,16 @@
+ #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>
+ #include <qfile.h>
+ #include <qbuffer.h>
+ #include <qmemarray.h>
+ #include <qimage.h>
+ #include <qmovie.h>
++#include <qpainter.h>
+ #include <qpopupmenu.h>
+ #include <qtimer.h>
+ #include <qheader.h>
+@@ -60,27 +62,46 @@
+ #include <stdlib.h>
+ #include <unistd.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;
+@@ -95,9 +116,24 @@
+ 		}
+ 		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;
+
+@@ -112,12 +148,14 @@
+   , 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 * )),
+@@ -125,10 +163,8 @@
+ 	}
+ 	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();
+@@ -147,6 +183,33 @@
+ 	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,
+@@ -160,6 +223,14 @@
+ 		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;
+ };
+
+@@ -188,10 +259,23 @@
+ 		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)
+@@ -244,7 +328,7 @@
+ }
+
+ void
+-KGreeter::insertUsers()
++KGreeter::insertUsers(int limit_users)
+ {
+ 	struct passwd *ps;
+
+@@ -271,6 +355,8 @@
+ 	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 ||
+@@ -282,10 +368,53 @@
+ 				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()) {
+@@ -687,21 +816,24 @@
+ 	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
+@@ -793,6 +925,9 @@
+ 	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" );
+@@ -818,37 +953,31 @@
+ 	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();
+ }
+
+@@ -866,8 +995,8 @@
+ 	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();
+@@ -883,12 +1012,17 @@
+ {
+ //	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;


More information about the Frugalware-git mailing list