summaryrefslogtreecommitdiffstats
path: root/opensuse/tdebase/kdm-make_it_cool.diff
diff options
context:
space:
mode:
Diffstat (limited to 'opensuse/tdebase/kdm-make_it_cool.diff')
-rw-r--r--opensuse/tdebase/kdm-make_it_cool.diff1534
1 files changed, 1534 insertions, 0 deletions
diff --git a/opensuse/tdebase/kdm-make_it_cool.diff b/opensuse/tdebase/kdm-make_it_cool.diff
new file mode 100644
index 000000000..fb1f5b076
--- /dev/null
+++ b/opensuse/tdebase/kdm-make_it_cool.diff
@@ -0,0 +1,1534 @@
+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;