summaryrefslogtreecommitdiffstats
path: root/kdm
diff options
context:
space:
mode:
Diffstat (limited to 'kdm')
-rw-r--r--kdm/backend/client.c93
-rw-r--r--kdm/config.def11
-rw-r--r--kdm/configure.in.in71
-rw-r--r--kdm/kfrontend/Makefile.am1
-rw-r--r--kdm/kfrontend/kdm_greet.c2
-rw-r--r--kdm/kfrontend/kdmadmindialog.cpp176
-rw-r--r--kdm/kfrontend/kdmadmindialog.h70
-rw-r--r--kdm/kfrontend/kdmconfig.cpp2
-rw-r--r--kdm/kfrontend/kdmconfig.h14
-rw-r--r--kdm/kfrontend/kfdialog.cpp4
-rw-r--r--kdm/kfrontend/kgapp.cpp5
-rw-r--r--kdm/kfrontend/kgdialog.cpp4
-rw-r--r--kdm/kfrontend/kgreeter.cpp214
-rw-r--r--kdm/kfrontend/kgreeter.h9
-rw-r--r--kdm/kfrontend/sessions/Makefile.am2
-rw-r--r--kdm/kfrontend/sessions/admin.desktop7
-rw-r--r--kdm/kfrontend/themer/kdmitem.cpp107
-rw-r--r--kdm/kfrontend/themer/kdmitem.h7
-rw-r--r--kdm/kfrontend/themer/kdmlabel.cpp67
-rw-r--r--kdm/kfrontend/themer/kdmlabel.h6
-rw-r--r--kdm/kfrontend/themer/kdmlayout.cpp9
-rw-r--r--kdm/kfrontend/themer/kdmpixmap.cpp98
-rw-r--r--kdm/kfrontend/themer/kdmpixmap.h5
-rw-r--r--kdm/kfrontend/themer/kdmrect.cpp32
-rw-r--r--kdm/kfrontend/themer/kdmrect.h4
-rw-r--r--kdm/kfrontend/themer/kdmthemer.cpp73
-rw-r--r--kdm/kfrontend/themer/kdmthemer.h4
27 files changed, 985 insertions, 112 deletions
diff --git a/kdm/backend/client.c b/kdm/backend/client.c
index b2e7ebbc7..0807b2ce7 100644
--- a/kdm/backend/client.c
+++ b/kdm/backend/client.c
@@ -87,6 +87,18 @@ extern int loginsuccess( const char *User, const char *Host, const char *Tty, ch
#include "consolekit.h"
#endif
+#define AU_FAILED 0
+#define AU_SUCCESS 1
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+#else
+#define log_to_audit_system(l,h,d,s) do { ; } while (0)
+#endif
+
+#ifdef WITH_CONSOLE_KIT
+#include "consolekit.h"
+#endif
+
/*
* Session data, mostly what struct verify_info was for
*/
@@ -291,6 +303,56 @@ fail_delay( int retval ATTR_UNUSED, unsigned usec_delay ATTR_UNUSED,
{}
# endif
+ /**
+ * log_to_audit_system:
+ * @login: Name of user
+ * @hostname: Name of host machine
+ * @tty: Name of display
+ * @success: 1 for success, 0 for failure
+ *
+ * Logs the success or failure of the login attempt with the linux kernel
+ * audit system. The intent is to capture failed events where the user
+ * fails authentication or otherwise is not permitted to login. There are
+ * many other places where pam could potentially fail and cause login to
+ * fail, but these are system failures rather than the signs of an account
+ * being hacked.
+ *
+ * Returns nothing.
+ */
+
+#ifdef HAVE_LIBAUDIT
+static void
+log_to_audit_system (const char *loginname,
+ const char *hostname,
+ const char *tty,
+ int success)
+{
+ struct passwd *pw;
+ char buf[64];
+ int audit_fd;
+
+ audit_fd = audit_open();
+ if (loginname)
+ pw = getpwnam(loginname);
+ else {
+ loginname = "unknown";
+ pw = NULL;
+ }
+ Debug("log_to_audit %p %s\n", pw, loginname);
+
+ if (pw) {
+ snprintf(buf, sizeof(buf), "uid=%d", pw->pw_uid);
+ audit_log_user_message(audit_fd, AUDIT_USER_LOGIN,
+ buf, hostname, NULL, tty, (int)success);
+ } else {
+ snprintf(buf, sizeof(buf), "acct=%s", loginname);
+ audit_log_user_message(audit_fd, AUDIT_USER_LOGIN,
+ buf, hostname, NULL, tty, (int)success);
+ }
+ close(audit_fd);
+}
+#endif
+
static int
doPAMAuth( const char *psrv, struct pam_data *pdata )
{
@@ -349,6 +411,8 @@ doPAMAuth( const char *psrv, struct pam_data *pdata )
GSendStr( curuser );
}
if (pretc != PAM_SUCCESS) {
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
switch (pretc) {
case PAM_USER_UNKNOWN:
case PAM_AUTH_ERR:
@@ -484,6 +548,9 @@ Verify( GConvFunc gconv, int rootok )
} else
psrv = PAMService;
pdata.usecur = TRUE;
+ } else if (!strcmp( curtype, "pam" )) {
+ psrv = PAMService;
+ pdata.usecur = FALSE;
} else {
sprintf( psrvb, "%.31s-%.31s", PAMService, curtype );
psrv = psrvb;
@@ -553,7 +620,7 @@ Verify( GConvFunc gconv, int rootok )
free( msg );
V_RET_FAIL( 0 );
}
- } else if (!strcmp( curtype, "generic" )) {
+ } else if (!strcmp( curtype, "generic" ) || !strcmp(curtype, "pam")) {
if (!gconv( GCONV_USER, 0 ))
return 0;
for (curret = 0;;) {
@@ -699,6 +766,8 @@ Verify( GConvFunc gconv, int rootok )
if (!p->pw_uid) {
if (!rootok && !td->allowRootLogin)
V_RET_FAIL( "Root logins are not allowed" );
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
return 1; /* don't deny root to log in */
}
@@ -735,6 +804,8 @@ Verify( GConvFunc gconv, int rootok )
}
if (pretc == PAM_SUCCESS)
break;
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
/* effectively there is only PAM_AUTHTOK_ERR */
GSendInt( V_FAIL );
}
@@ -824,6 +895,8 @@ Verify( GConvFunc gconv, int rootok )
GSendInt( V_MSG_ERR );
GSendStr( "Your account has expired;"
" please contact your system administrator" );
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
GSendInt( V_FAIL );
LC_RET0;
} else if (tim > (expir - warntime) && !quietlog) {
@@ -858,6 +931,8 @@ Verify( GConvFunc gconv, int rootok )
GSendInt( V_MSG_ERR );
GSendStr( "Your account has expired;"
" please contact your system administrator" );
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
GSendInt( V_FAIL );
LC_RET0;
}
@@ -917,6 +992,8 @@ Verify( GConvFunc gconv, int rootok )
close( fd );
}
GSendStr( "Logins are not allowed at the moment.\nTry again later" );
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
GSendInt( V_FAIL );
LC_RET0;
}
@@ -927,6 +1004,8 @@ Verify( GConvFunc gconv, int rootok )
PrepErrorGreet();
GSendInt( V_MSG_ERR );
GSendStr( "You are not allowed to login at the moment" );
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
GSendInt( V_FAIL );
LC_RET0;
}
@@ -938,6 +1017,8 @@ Verify( GConvFunc gconv, int rootok )
Debug( "shell not in /etc/shells\n" );
endusershell();
V_RET_FAIL( "Your login shell is not listed in /etc/shells" );
+ /* Log the failed login attempt */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED);
}
if (!strcmp( s, p->pw_shell )) {
endusershell();
@@ -1223,6 +1304,8 @@ StartClient()
env = setEnv( env, "PATH", curuid ? td->userPath : td->systemPath );
env = setEnv( env, "SHELL", p->pw_shell );
env = setEnv( env, "HOME", p->pw_dir );
+ if (cursource == PWSRC_AUTOLOGIN)
+ env = setEnv (env, "KDM_AUTOLOGIN", curuser);
#if !defined(USE_PAM) && !defined(_AIX) && defined(KERBEROS)
if (krbtkfile[0] != '\0')
env = setEnv( env, "KRBTKFILE", krbtkfile );
@@ -1232,6 +1315,11 @@ StartClient()
env = setEnv ( env, "XDG_SESSION_COOKIE", ck_session_cookie );
}
#endif
+#ifdef WITH_CONSOLE_KIT
+ if (ck_session_cookie != NULL) {
+ env = setEnv ( env, "XDG_SESSION_COOKIE", ck_session_cookie );
+ }
+#endif
userEnviron = inheritEnv( env, envvars );
env = systemEnv( p->pw_name );
systemEnviron = setEnv( env, "HOME", p->pw_dir );
@@ -1360,6 +1448,9 @@ StartClient()
# define D_LOGIN_SETGROUP 0
#endif /* USE_PAM */
+ /* Login succeeded */
+ log_to_audit_system (curuser, td->remoteHost, td->name, AU_SUCCESS);
+
removeAuth = 1;
chownCtrl( &td->ctrl, curuid );
endpwent();
diff --git a/kdm/config.def b/kdm/config.def
index ab1adac84..7bc39b36d 100644
--- a/kdm/config.def
+++ b/kdm/config.def
@@ -1985,6 +1985,17 @@ Description:
Specify the widget style for the greeter. Empty means to use the
built-in default which currently is <literal>Plastik</literal>.
+Key: UseAdminSession
+Type: bool
+Default: false
+User: greeter
+Instance: #*/!
+Comment:
+ Admin session
+Description:
+ If given there will be a special button that requires root password
+ and starts the given session
+
Key: ColorScheme
Type: string
Default: ""
diff --git a/kdm/configure.in.in b/kdm/configure.in.in
index 4b6972178..da741e7f9 100644
--- a/kdm/configure.in.in
+++ b/kdm/configure.in.in
@@ -287,4 +287,75 @@ fi
AC_SUBST(DBUS_INCS)
AC_SUBST(DBUS_LIBS)
+########### Check for DBus
+
+ AC_MSG_CHECKING(for DBus)
+
+ dbus_inc=NOTFOUND
+ dbus_lib=NOTFOUND
+ dbus=NOTFOUND
+
+ search_incs="$kde_includes $kde_extra_includes /usr/include /usr/include/dbus-1.0 /usr/local/include /usr/local/include/dbus-1.0"
+ AC_FIND_FILE(dbus/dbus.h, $search_incs, dbus_incdir)
+
+ search_incs_arch_deps="$kde_includes $kde_extra_includes /usr/lib$kdelibsuff/dbus-1.0/include /usr/local/lib$kdelibsuff/dbus-1.0/include"
+ AC_FIND_FILE(dbus/dbus-arch-deps.h, $search_incs_arch_deps, dbus_incdir_arch_deps)
+
+ if test -r $dbus_incdir/dbus/dbus.h && test -r $dbus_incdir_arch_deps/dbus/dbus-arch-deps.h ; then
+ DBUS_INCS="-I$dbus_incdir -I$dbus_incdir_arch_deps"
+ dbus_inc=FOUND
+ fi
+
+ search_libs="$kde_libraries $kde_extra_libs /usr/lib$kdelibsuff /usr/local/lib$kdelibsuff"
+ AC_FIND_FILE(libdbus-1.so, $search_libs, dbus_libdir)
+
+ if test -r $dbus_libdir/libdbus-1.so ; then
+ DBUS_LIBS="-L$dbus_libdir -ldbus-1"
+ dbus_lib=FOUND
+ fi
+
+ if test $dbus_inc != FOUND || test $dbus_lib != FOUND ; then
+ KDE_PKG_CHECK_MODULES( DBUS, "dbus-1", [ DBUS_INCS=$DBUS_CFLAGS; dbus_inc=FOUND; dbus_lib=FOUND; ] , AC_MSG_RESULT( Nothing found on PKG_CONFIG_PATH ) )
+ fi
+
+ dbus_bus_var=`pkg-config --variable=system_bus_default_address dbus-1 2>/dev/null`
+ if test -z "$dbus_bus_var"; then
+ dbus_bus_var="unix:path=/var/run/dbus/system_bus_socket"
+ fi
+ AC_DEFINE_UNQUOTED(DBUS_SYSTEM_BUS, "$dbus_bus_var", [Define the unix domain path for dbus system bus])
+
+ if test $dbus_inc = FOUND && test $dbus_lib = FOUND ; then
+ AC_MSG_RESULT(headers $DBUS_INCS libraries $DBUS_LIBS)
+ dbus=FOUND
+ else
+ AC_MSG_RESULT(searched but not found)
+ fi
+
+ AC_SUBST(DBUS_INCS)
+ AC_SUBST(DBUS_LIBS)
+
dnl AC_OUTPUT(kdm/kfrontend/sessions/kde.desktop)
+
+
+AC_ARG_WITH(libaudit,
+ [ --with-libaudit=[auto/yes/no] Add Linux audit support [default=auto]],,
+ with_libaudit=auto)
+
+# Check for Linux auditing API
+#
+# libaudit detection
+if test x$with_libaudit = xno ; then
+ have_libaudit=no;
+else
+ # See if we have audit daemon library
+ AC_CHECK_LIB(audit, audit_log_user_message,
+ have_libaudit=yes, have_libaudit=no)
+fi
+
+AM_CONDITIONAL(HAVE_LIBAUDIT, test x$have_libaudit = xyes)
+
+if test x$have_libaudit = xyes ; then
+ EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -laudit"
+ AC_DEFINE(HAVE_LIBAUDIT,1,[linux audit support])
+fi
+
diff --git a/kdm/kfrontend/Makefile.am b/kdm/kfrontend/Makefile.am
index 5c5dfd61a..6d4fed27b 100644
--- a/kdm/kfrontend/Makefile.am
+++ b/kdm/kfrontend/Makefile.am
@@ -21,6 +21,7 @@ kdm_greet_SOURCES = \
kchooser.cpp \
kgverify.cpp \
kdmshutdown.cpp \
+ kdmadmindialog.cpp \
kgreeter.cpp \
kgapp.cpp
kdm_greet_LDFLAGS = $(all_libraries) $(KDE_RPATH)
diff --git a/kdm/kfrontend/kdm_greet.c b/kdm/kfrontend/kdm_greet.c
index 53d164f45..b03d96e15 100644
--- a/kdm/kfrontend/kdm_greet.c
+++ b/kdm/kfrontend/kdm_greet.c
@@ -44,8 +44,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# include <sched.h>
#endif
-#if defined(HAVE_XTEST) || defined(HAVE_XKB)
# include <X11/Xlib.h>
+#if defined(HAVE_XTEST) || defined(HAVE_XKB)
# include <X11/keysym.h>
#endif
diff --git a/kdm/kfrontend/kdmadmindialog.cpp b/kdm/kfrontend/kdmadmindialog.cpp
new file mode 100644
index 000000000..637d6dd90
--- /dev/null
+++ b/kdm/kfrontend/kdmadmindialog.cpp
@@ -0,0 +1,176 @@
+ /*
+
+ Admin dialog
+
+ Copyright (C) 1997, 1998, 2000 Steffen Hansen <hansen@kde.org>
+ Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org>
+
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include "kdmadmindialog.h"
+#include "kdmconfig.h"
+#include "kgdialog.h"
+#include "kdm_greet.h"
+#include <stdlib.h>
+
+#include <kapplication.h>
+#include <kseparator.h>
+#include <klocale.h>
+#include <kpushbutton.h>
+#include <kstdguiitem.h>
+
+#include <tqcombobox.h>
+#include <tqvbuttongroup.h>
+#include <tqstyle.h>
+#include <tqlayout.h>
+#include <tqaccel.h>
+#include <tqpopupmenu.h>
+
+int KDMAdmin::curPlugin = -1;
+PluginList KDMAdmin::pluginList;
+
+KDMAdmin::KDMAdmin( const TQString &user, TQWidget *_parent )
+ : inherited( _parent )
+ , verify( 0 ), curUser(user)
+{
+ TQSizePolicy fp( TQSizePolicy::Fixed, TQSizePolicy::Fixed );
+
+ TQVBoxLayout *box = new TQVBoxLayout( this, 10 );
+
+ TQHBoxLayout *hlay = new TQHBoxLayout( box );
+
+ GSendInt( G_ReadDmrc );
+ GSendStr( "root" );
+ GRecvInt(); // ignore status code ...
+
+ if (curPlugin < 0) {
+ curPlugin = 0;
+ pluginList = KGVerify::init( "classic" );
+ }
+ verify = new KGStdVerify( this, this,
+ this, "root",
+ pluginList, KGreeterPlugin::Authenticate,
+ KGreeterPlugin::Shutdown );
+ verify->selectPlugin( curPlugin );
+ box->addLayout( verify->getLayout() );
+ TQAccel *accel = new TQAccel( this );
+ accel->insertItem( ALT+Key_A, 0 );
+ connect( accel, TQT_SIGNAL(activated(int)), TQT_SLOT(slotActivatePlugMenu()) );
+
+ box->addWidget( new KSeparator( KSeparator::HLine, this ) );
+
+ okButton = new KPushButton( KStdGuiItem::ok(), this );
+ okButton->setSizePolicy( fp );
+ okButton->setDefault( true );
+ cancelButton = new KPushButton( KStdGuiItem::cancel(), this );
+ cancelButton->setSizePolicy( fp );
+
+ hlay = new TQHBoxLayout( box );
+ hlay->addStretch( 1 );
+ hlay->addWidget( okButton );
+ hlay->addStretch( 1 );
+ hlay->addWidget( cancelButton );
+ hlay->addStretch( 1 );
+
+ connect( okButton, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) );
+ connect( cancelButton, TQT_SIGNAL(clicked()), TQT_SLOT(reject()) );
+
+ slotWhenChanged();
+}
+
+KDMAdmin::~KDMAdmin()
+{
+ hide();
+ delete verify;
+}
+
+void
+KDMAdmin::slotActivatePlugMenu()
+{
+ TQPopupMenu *cmnu = verify->getPlugMenu();
+ TQSize sh( cmnu->sizeHint() / 2 );
+ cmnu->exec( geometry().center() - TQPoint( sh.width(), sh.height() ) );
+}
+
+void
+KDMAdmin::accept()
+{
+ verify->accept();
+}
+
+void
+KDMAdmin::slotWhenChanged()
+{
+ verify->abort();
+ verify->setEnabled( 1 );
+ verify->start();
+}
+
+void
+KDMAdmin::bye_bye()
+{
+ GSendInt( G_GetDmrc );
+ GSendStr( "Session" );
+ char *sess = GRecvStr();
+ if (sess && strcmp(sess, "admin")) {
+ GSendInt( G_PutDmrc );
+ GSendStr( "OrigSession");
+ GSendStr( sess);
+ free(sess);
+ }
+
+ GSendInt( G_PutDmrc );
+ GSendStr( "Session" );
+ GSendStr( "admin" );
+ inherited::accept();
+}
+
+void
+KDMAdmin::verifyPluginChanged( int id )
+{
+ curPlugin = id;
+ adjustSize();
+}
+
+void
+KDMAdmin::verifyOk()
+{
+ bye_bye();
+}
+
+void
+KDMAdmin::verifyFailed()
+{
+ okButton->setEnabled( false );
+ cancelButton->setEnabled( false );
+}
+
+void
+KDMAdmin::verifyRetry()
+{
+ okButton->setEnabled( true );
+ cancelButton->setEnabled( true );
+}
+
+void
+KDMAdmin::verifySetUser( const TQString & )
+{
+}
+
+
+#include "kdmadmindialog.moc"
diff --git a/kdm/kfrontend/kdmadmindialog.h b/kdm/kfrontend/kdmadmindialog.h
new file mode 100644
index 000000000..91f1ed3a6
--- /dev/null
+++ b/kdm/kfrontend/kdmadmindialog.h
@@ -0,0 +1,70 @@
+ /*
+
+ Shutdown dialog
+
+ Copyright (C) 1997, 1998 Steffen Hansen <hansen@kde.org>
+ Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org>
+
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+
+#ifndef KDMADMIN_H
+#define KDMADMIN_H
+
+#include "kgverify.h"
+
+#include <tqradiobutton.h>
+
+class LiloInfo;
+class TQLabel;
+class KPushButton;
+class TQButtonGroup;
+class TQComboBox;
+
+class KDMAdmin : public FDialog, public KGVerifyHandler {
+ Q_OBJECT
+ typedef FDialog inherited;
+
+public:
+ KDMAdmin( const TQString &user, TQWidget *_parent = 0 );
+ ~KDMAdmin();
+
+public slots:
+ void accept();
+ void slotWhenChanged();
+ void slotActivatePlugMenu();
+
+private:
+ void bye_bye();
+
+ KPushButton *okButton, *cancelButton;
+ KGStdVerify *verify;
+ TQString curUser;
+
+ static int curPlugin;
+ static PluginList pluginList;
+
+public: // from KGVerifyHandler
+ virtual void verifyPluginChanged( int id );
+ virtual void verifyOk();
+ virtual void verifyFailed();
+ virtual void verifyRetry();
+ virtual void verifySetUser( const TQString &user );
+};
+
+#endif
diff --git a/kdm/kfrontend/kdmconfig.cpp b/kdm/kfrontend/kdmconfig.cpp
index 6f4c14031..15a63fa67 100644
--- a/kdm/kfrontend/kdmconfig.cpp
+++ b/kdm/kfrontend/kdmconfig.cpp
@@ -33,6 +33,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <unistd.h>
#include <sys/utsname.h>
+struct timeval st = {0, 0};
+
CONF_GREET_DEFS
TQString _stsFile;
diff --git a/kdm/kfrontend/kdmconfig.h b/kdm/kfrontend/kdmconfig.h
index f5420bcc4..52e054af6 100644
--- a/kdm/kfrontend/kdmconfig.h
+++ b/kdm/kfrontend/kdmconfig.h
@@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <tqstring.h>
#include <tqstringlist.h>
#include <tqfont.h>
+#include <sys/time.h>
extern TQString _stsFile;
extern bool _isLocal;
@@ -46,6 +47,19 @@ CONF_GREET_CPP_DECLS
struct dpySpec;
void decodeSess( dpySpec *sess, TQString &user, TQString &loc );
+extern struct timeval st;
+
+inline TQString timestamp() {
+ struct timeval nst;
+ gettimeofday(&nst, 0);
+ if (!st.tv_sec)
+ gettimeofday(&st, 0);
+
+ TQString ret;
+ ret.sprintf("[%07ld]", (nst.tv_sec - st.tv_sec) * 1000 + (nst.tv_usec - st.tv_usec) / 1000);
+ return ret;
+}
+
extern "C"
#endif
void init_config( void );
diff --git a/kdm/kfrontend/kfdialog.cpp b/kdm/kfrontend/kfdialog.cpp
index 62a4acb22..78359e237 100644
--- a/kdm/kfrontend/kfdialog.cpp
+++ b/kdm/kfrontend/kfdialog.cpp
@@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <klocale.h>
#include <kpushbutton.h>
#include <kstdguiitem.h>
+#include <kglobalsettings.h>
#include <tqlabel.h>
#include <tqlayout.h>
@@ -137,6 +138,9 @@ KFMsgBox::KFMsgBox( TQWidget *parent, TQMessageBox::Icon type, const TQString &t
TQLabel *label1 = new TQLabel( this );
label1->setPixmap( TQMessageBox::standardIcon( type ) );
TQLabel *label2 = new TQLabel( text, this );
+ TQRect d = KGlobalSettings::desktopGeometry(this);
+ if ( label2->fontMetrics().size( 0, text).width() > d.width() * 3 / 5)
+ label2->setAlignment(Qt::WordBreak | Qt::AlignAuto );
KPushButton *button = new KPushButton( KStdGuiItem::ok(), this );
button->setDefault( true );
button->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred ) );
diff --git a/kdm/kfrontend/kgapp.cpp b/kdm/kfrontend/kgapp.cpp
index 70b510645..50e65e916 100644
--- a/kdm/kfrontend/kgapp.cpp
+++ b/kdm/kfrontend/kgapp.cpp
@@ -36,6 +36,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <kcrash.h>
#include <kstandarddirs.h>
#include <ksimpleconfig.h>
+#include <klocale.h>
+#include <kdebug.h>
#include <tqtimer.h>
#include <tqstring.h>
@@ -133,6 +135,7 @@ kg_main( const char *argv0 )
static char *argv[] = { (char *)"kdmgreet", 0 };
KCmdLineArgs::init( 1, argv, *argv, 0, 0, 0, true );
+ kdDebug() << timestamp() << "start" << endl;
kde_have_kipc = false;
KApplication::disableAutoDcopRegistration();
KCrash::setSafer( true );
@@ -180,6 +183,7 @@ kg_main( const char *argv0 )
GSendInt( G_Ready );
+ kdDebug() << timestamp() << " main1" << endl;
setCursor( dpy, app.desktop()->winId(), XC_left_ptr );
for (;;) {
@@ -220,6 +224,7 @@ kg_main( const char *argv0 )
if (_useTheme && !_theme.isEmpty()) {
KThemedGreeter *tgrt;
dialog = tgrt = new KThemedGreeter;
+ kdDebug() << timestamp() << " themed" << endl;
if (!tgrt->isOK()) {
delete tgrt;
dialog = new KStdGreeter;
diff --git a/kdm/kfrontend/kgdialog.cpp b/kdm/kfrontend/kgdialog.cpp
index 1981eea83..f4ed918c6 100644
--- a/kdm/kfrontend/kgdialog.cpp
+++ b/kdm/kfrontend/kgdialog.cpp
@@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "kdm_greet.h"
#include <klocale.h>
+#include <kiconloader.h>
#include <tqaccel.h>
#include <tqlayout.h>
@@ -84,7 +85,8 @@ KGDialog::completeMenu()
inserten( i18n("Co&nsole Login"), ALT+Key_N, TQT_SLOT(slotConsole()) );
if (_allowShutdown != SHUT_NONE) {
- inserten( i18n("&Shutdown..."), ALT+Key_S, TQT_SLOT(slotShutdown( int )) );
+ ensureMenu();
+ optMenu->insertItem(SmallIconSet( "exit" ), i18n("&Shutdown..."), this, TQT_SLOT(slotShutdown(int)), ALT+Key_S );
TQAccel *accel = new TQAccel( this );
accel->insertItem( ALT+CTRL+Key_Delete );
connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotShutdown( int )) );
diff --git a/kdm/kfrontend/kgreeter.cpp b/kdm/kfrontend/kgreeter.cpp
index ebd303525..74fc6b090 100644
--- a/kdm/kfrontend/kgreeter.cpp
+++ b/kdm/kfrontend/kgreeter.cpp
@@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "kdmconfig.h"
#include "kdmclock.h"
#include "kdm_greet.h"
+#include "kdmadmindialog.h"
#include "themer/kdmthemer.h"
#include "themer/kdmitem.h"
#include "themer/kdmlabel.h"
@@ -38,6 +39,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <klistview.h>
#include <ksimpleconfig.h>
#include <kstringhandler.h>
+#include <kdebug.h>
#undef Unsorted // x headers suck - make tqdir.h work with --enable-final
#include <tqdir.h>
@@ -46,6 +48,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <tqmemarray.h>
#include <tqimage.h>
#include <tqmovie.h>
+#include <tqpainter.h>
#include <tqpopupmenu.h>
#include <tqtimer.h>
#include <tqheader.h>
@@ -57,6 +60,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <tqaccel.h>
#include <tqstring.h>
#include <tqeventloop.h>
+#include <tqbitmap.h>
#include <pwd.h>
#include <grp.h>
@@ -64,27 +68,46 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
+#include <utmp.h>
+#include <utmpx.h>
#include <X11/Xlib.h>
class UserListView : public KListView {
public:
- UserListView( TQWidget *parent = 0, const char *name = 0 )
+ UserListView( bool _them, TQWidget *parent = 0, const char *name = 0 )
: KListView( parent, name )
- , cachedSizeHint( -1, 0 )
+ , themed(_them), cachedSizeHint( -1, 0 )
{
setSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Ignored );
header()->hide();
addColumn( TQString::null );
setColumnAlignment( 0, AlignVCenter );
setResizeMode( TQListView::LastColumn );
+ if (themed) {
+ setBackgroundMode( Qt::NoBackground );
+ viewport()->setBackgroundMode( Qt::NoBackground );
+ setFrameStyle( TQFrame::NoFrame );
+ }
}
+ bool themed;
mutable TQSize cachedSizeHint;
- protected:
+ int sumHeight() const
+ {
+ int sum = 0;
+ for (TQListViewItem *itm = firstChild(); itm; itm = itm->nextSibling()) {
+ sum += itm->height();
+ }
+ return sum;
+ }
+public:
virtual TQSize sizeHint() const
{
+ if (themed)
+ return KListView::sizeHint();
+
if (!cachedSizeHint.isValid()) {
constPolish();
uint maxw = 0;
@@ -99,9 +122,24 @@ class UserListView : public KListView {
}
return cachedSizeHint;
}
+ virtual void paintEmptyArea ( TQPainter * p, const TQRect & rect )
+ {
+ if (!themed)
+ return KListView::paintEmptyArea(p, rect );
+
+ const TQPixmap *pm = paletteBackgroundPixmap();
+ if (!pm || pm->isNull())
+ return;
+
+ kdDebug() << "paintEmpty " << rect << endl;
+ TQRect devRect = p->xForm( rect );
+ kdDebug() << "paintEmpty2 " << devRect << endl;
+ p->drawPixmap(0, 0, *pm, devRect.left(), devRect.top() );
+ }
+
+ TQPixmap background;
};
-
int KGreeter::curPlugin = -1;
PluginList KGreeter::pluginList;
@@ -116,12 +154,14 @@ KGreeter::KGreeter( bool framed )
, curSel( -1 )
, prevValid( true )
, needLoad( false )
+ , themed( framed )
{
stsFile = new KSimpleConfig( _stsFile );
stsFile->setGroup( "PrevUser" );
if (_userList) {
- userView = new UserListView( this );
+ readFacesList();
+ userView = new UserListView( framed, this );
connect( userView, TQT_SIGNAL(clicked( TQListViewItem * )),
TQT_SLOT(slotUserClicked( TQListViewItem * )) );
connect( userView, TQT_SIGNAL(doubleClicked( TQListViewItem * )),
@@ -129,10 +169,8 @@ KGreeter::KGreeter( bool framed )
}
if (_userCompletion)
userList = new TQStringList;
- if (userView || userList)
- insertUsers();
- sessMenu = new TQPopupMenu( this );
+ sessMenu = new TQPopupMenu( this );
connect( sessMenu, TQT_SIGNAL(activated( int )),
TQT_SLOT(slotSessionSelected( int )) );
insertSessions();
@@ -151,6 +189,33 @@ KGreeter::~KGreeter()
delete stsFile;
}
+void KGreeter::readFacesList()
+{
+ FILE *f = fopen( TQFile::encodeName( _faceDir + "/.randomlist" ), "rt" );
+ if ( !f )
+ return;
+ TQTextIStream is( f );
+ while ( !is.eof() )
+ {
+ TQString line = is.readLine().simplifyWhiteSpace();
+ if ( line.isEmpty() )
+ continue;
+ TQString icon;
+ int index = line.find( ' ' );
+ if ( index > 0 ) {
+ icon = line.left( index );
+ line = line.mid( index );
+ } else {
+ icon = line;
+ line = TQString::null;
+ }
+ randomFaces.push_back( icon );
+ TQStringList list = TQStringList::split( ' ', line );
+ for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
+ randomFacesMap[*it] = icon;
+ }
+}
+
class UserListViewItem : public KListViewItem {
public:
UserListViewItem( UserListView *parent, const TQString &text,
@@ -164,6 +229,14 @@ class UserListViewItem : public KListViewItem {
parent->cachedSizeHint.setWidth( -1 );
}
+ virtual void paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int alignment)
+ {
+ if (((UserListView*)listView())->themed)
+ TQListViewItem::paintCell(p, cg, column, width, alignment);
+ else
+ KListViewItem::paintCell(p, cg, column, width, alignment);
+ }
+
TQString login;
};
@@ -232,10 +305,23 @@ KGreeter::insertUser( const TQImage &default_pix,
TQSize ns( 48, 48 );
if (p.size() != ns)
p = p.convertDepth( 32 ).smoothScale( ns, TQImage::ScaleMin );
- goto gotit;
+ break;
} while (--nd >= 0);
- p = default_pix;
- gotit:
+
+ if ( p.isNull() && randomFaces.count() ) {
+ TQString randomFace = randomFacesMap[username];
+ if ( randomFace.isNull() ) {
+ TQStringList::size_type index = 0;
+ for ( size_t i = 0; i < username.length(); ++i )
+ index += ( 0x7f - username.at( i ).latin1() ) % 37;
+ randomFace = randomFaces[ index % randomFaces.count() ];
+ }
+ p.load( _faceDir + "/../pics/users/" + randomFace + ".png" );
+ }
+
+ if ( p.isNull() )
+ p = default_pix;
+
TQString realname = KStringHandler::from8Bit( ps->pw_gecos );
realname.truncate( realname.find( ',' ) );
if (realname.isEmpty() || realname == username)
@@ -289,7 +375,7 @@ UserList::UserList( char **in )
}
void
-KGreeter::insertUsers()
+KGreeter::insertUsers(int limit_users)
{
struct passwd *ps;
@@ -309,6 +395,8 @@ KGreeter::insertUsers()
if (_showUsers == SHOW_ALL) {
UserList noUsers( _noUsers );
TQDict<int> dupes( 1000 );
+ TQStringList toinsert;
+ int count = 0;
for (setpwent(); (ps = getpwent()) != 0;) {
if (*ps->pw_dir && *ps->pw_shell &&
(ps->pw_uid >= (unsigned)_lowUserId ||
@@ -320,10 +408,53 @@ KGreeter::insertUsers()
TQString username( TQFile::decodeName( ps->pw_name ) );
if (!dupes.find( username )) {
dupes.insert( username, (int *)-1 );
- insertUser( default_pix, username, ps );
+ toinsert.append( username );
+
+ if ( limit_users >= 0 && ++count > limit_users )
+ break;
}
}
}
+ if ( limit_users >= 0 && ++count > limit_users ) {
+ utmpname( _PATH_WTMP );
+ setutxent();
+ toinsert = TQStringList();
+ dupes.clear();
+
+ for ( count = 0; count < limit_users; ) {
+ struct utmpx * ent = getutxent();
+ if ( !ent )
+ break;
+ struct passwd *ps = getpwnam( ent->ut_user );
+ if (ps && *ps->pw_dir && *ps->pw_shell &&
+ (ps->pw_uid >= (unsigned)_lowUserId ||
+ !ps->pw_uid && _showRoot) &&
+ ps->pw_uid <= (unsigned)_highUserId &&
+ !noUsers.hasUser( ps->pw_name ) &&
+ !noUsers.hasGroup( ps->pw_gid ))
+ {
+ TQString username( TQFile::decodeName( ent->ut_user ) );
+ if (!dupes.find( username )) {
+ dupes.insert( username, (int *)-1 );
+ toinsert.append( username );
+ count++;
+ }
+ }
+
+
+ }
+ endutxent();
+ }
+
+ for ( TQStringList::ConstIterator it = toinsert.begin();
+ it != toinsert.end(); ++it )
+ {
+ // pretty stupid to do another lookup round, but the number is limited
+ // and caching struct passwd is pretty ugly
+ struct passwd *ps = getpwnam( TQFile::encodeName( *it ) );
+ if ( ps )
+ insertUser( default_pix, *it, ps );
+ }
} else {
UserList users( _users );
if (users.hasGroups()) {
@@ -379,7 +510,7 @@ KGreeter::insertSessions()
for (char **dit = _sessionsDirs; *dit; ++dit) {
TQStringList ents = TQDir( *dit ).entryList();
for (TQStringList::ConstIterator it = ents.begin(); it != ents.end(); ++it)
- if ((*it).endsWith( ".desktop" )) {
+ if ((*it).endsWith( ".desktop" ) && !(*it).endsWith("admin.desktop")) {
KSimpleConfig dsk( TQString( *dit ).append( '/' ).append( *it ) );
dsk.setGroup( "Desktop Entry" );
putSession( (*it).left( (*it).length() - 8 ),
@@ -517,6 +648,17 @@ KGreeter::slotLoadPrevWM()
return;
}
} else {
+ if (!strcmp(sess, "admin")) {
+ // need to get the original
+ GSendInt( G_GetDmrc);
+ GSendStr( "OrigSession");
+ sess = GRecvStr();
+ if (!sess) {
+ free(sess);
+ sess = strdup("default");
+ }
+ }
+
for (uint i = 0; i < sessionTypes.count() && !sessionTypes[i].hid; i++)
if (sessionTypes[i].type == sess) {
free( sess );
@@ -718,21 +860,24 @@ KStdGreeter::KStdGreeter()
hbox2->addStretch( 1 );
if (sessMenu->count() > 1) {
- inserten( i18n("Session &Type"), ALT+Key_T, sessMenu );
+ inserten( i18n("Session &Type"), 0, sessMenu );
needSep = true;
}
if (plugMenu) {
- inserten( i18n("&Authentication Method"), ALT+Key_A, plugMenu );
+ inserten( i18n("&Authentication Method"), 0, plugMenu );
needSep = true;
}
#ifdef XDMCP
- completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), ALT+Key_R );
+ completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), 0 );
#else
completeMenu();
#endif
+ if (userView || userList)
+ insertUsers();
+
if (optMenu)
menuButton->setPopup( optMenu );
else
@@ -826,6 +971,9 @@ KThemedGreeter::KThemedGreeter()
if (xauth_warning && (_authorized || !_authComplain))
xauth_warning->hide( true );
+ if (userView || userList)
+ insertUsers( 7 ); // TODO: find out how many are a good value
+
// if (!_greetString.isEmpty()) {
// }
// clock = new KdmClock( this, "clock" );
@@ -851,12 +999,8 @@ KThemedGreeter::KThemedGreeter()
if ((itm = themer->findNode( "session_button" ))) {
if (sessMenu->count() <= 1)
itm->hide( true );
- else {
+ else
session_button = itm;
- TQAccel *accel = new TQAccel( this );
- accel->insertItem( ALT+Key_T, 0 );
- connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotSessMenu()) );
- }
} else {
if (sessMenu->count() > 1) {
inserten( i18n("Session &Type"), ALT+Key_T, sessMenu );
@@ -864,6 +1008,12 @@ KThemedGreeter::KThemedGreeter()
}
}
+ admin_button = themer->findNode( "admin_button");
+ if ( admin_button ) {
+ if ( !_useAdminSession )
+ admin_button->hide( true );
+ }
+
if (plugMenu) {
inserten( i18n("&Authentication Method"), ALT+Key_A, plugMenu );
needSep = true;
@@ -899,8 +1049,8 @@ KThemedGreeter::pluginSetup()
inherited::pluginSetup();
if (userView && verify->entitiesLocal() && verify->entityPresettable() && userlist_rect) {
+ userView->setMaximumHeight( userView->sumHeight() );
userlist_rect->setWidget( userView );
- userView->show();
} else {
if (userView)
userView->hide();
@@ -916,12 +1066,17 @@ KThemedGreeter::verifyFailed()
{
// goButton->setEnabled( false );
inherited::verifyFailed();
+ if (userView)
+ userView->setEnabled(false);
}
void
KThemedGreeter::verifyRetry()
{
// goButton->setEnabled( true );
+ if (userView)
+ userView->setEnabled(true);
+
}
TQString KThemedGreeter::timedUser = TQString::null;
@@ -966,6 +1121,8 @@ KThemedGreeter::slotThemeActivated( const TQString &id )
slotSessMenu();
else if (id == "system_button")
slotActionMenu();
+ else if (id == "admin_button")
+ slotAskAdminPassword();
}
void
@@ -992,4 +1149,15 @@ KThemedGreeter::keyPressEvent( TQKeyEvent *e )
accept();
}
+void
+KThemedGreeter::slotAskAdminPassword()
+{
+ KDMAdmin k(curUser, this);
+ if (k.exec()) {
+ GSendInt(G_Ready);
+ hide();
+ done(ex_exit);
+ }
+}
+
#include "kgreeter.moc"
diff --git a/kdm/kfrontend/kgreeter.h b/kdm/kfrontend/kgreeter.h
index 61673badf..fdbd56209 100644
--- a/kdm/kfrontend/kgreeter.h
+++ b/kdm/kfrontend/kgreeter.h
@@ -73,9 +73,10 @@ class KGreeter : public KGDialog, public KGVerifyHandler {
void slotUserEntered();
protected:
+ void readFacesList();
void installUserList();
void insertUser( const TQImage &, const TQString &, struct passwd * );
- void insertUsers();
+ void insertUsers( int limit = -1);
void putSession( const TQString &, const TQString &, bool, const char * );
void insertSessions();
virtual void pluginSetup();
@@ -87,10 +88,13 @@ class KGreeter : public KGDialog, public KGVerifyHandler {
TQStringList *userList;
TQPopupMenu *sessMenu;
TQValueVector<SessType> sessionTypes;
+ TQStringList randomFaces;
+ TQMap<TQString, TQString> randomFacesMap;
int nNormals, nSpecials;
int curPrev, curSel;
bool prevValid;
bool needLoad;
+ bool themed;
static int curPlugin;
static PluginList pluginList;
@@ -142,6 +146,7 @@ class KThemedGreeter : public KGreeter {
void slotThemeActivated( const TQString &id );
void slotSessMenu();
void slotActionMenu();
+ void slotAskAdminPassword();
protected:
virtual void updateStatus( bool fail, bool caps, int timedleft );
@@ -154,7 +159,7 @@ class KThemedGreeter : public KGreeter {
KdmThemer *themer;
KdmItem *caps_warning, *xauth_warning, *pam_error, *timed_label,
*console_rect, *userlist_rect,
- *session_button, *system_button;
+ *session_button, *system_button, *admin_button;
public: // from KGVerifyHandler
virtual void verifyFailed();
diff --git a/kdm/kfrontend/sessions/Makefile.am b/kdm/kfrontend/sessions/Makefile.am
index 14577ac42..71655c9a4 100644
--- a/kdm/kfrontend/sessions/Makefile.am
+++ b/kdm/kfrontend/sessions/Makefile.am
@@ -1,6 +1,6 @@
sessionsdir = $(kde_datadir)/kdm/sessions
sessions_DATA = \
- kde.desktop gnome.desktop \
+ admin.desktop kde.desktop gnome.desktop \
9wm.desktop \
aewm++.desktop \
aewm.desktop \
diff --git a/kdm/kfrontend/sessions/admin.desktop b/kdm/kfrontend/sessions/admin.desktop
new file mode 100644
index 000000000..73e6ae3bf
--- /dev/null
+++ b/kdm/kfrontend/sessions/admin.desktop
@@ -0,0 +1,7 @@
+[Desktop Entry]
+Encoding=UTF-8
+Type=XSession
+Exec=YaSTadminSession
+TryExec=YaSTadminSession
+Name=admin
+Comment=Yast Admin Session
diff --git a/kdm/kfrontend/themer/kdmitem.cpp b/kdm/kfrontend/themer/kdmitem.cpp
index 38af9d0aa..d47c0242d 100644
--- a/kdm/kfrontend/themer/kdmitem.cpp
+++ b/kdm/kfrontend/themer/kdmitem.cpp
@@ -23,10 +23,11 @@
* Generic Kdm Item
*/
-//#define DRAW_OUTLINE 1 // for debugging only
+// #define DRAW_OUTLINE 1 // for debugging only
#include "kdmitem.h"
#include "kdmlayout.h"
+#include "kdmconfig.h"
#include <kglobal.h>
#include <kdebug.h>
@@ -35,9 +36,7 @@
#include <tqwidget.h>
#include <tqlayout.h>
#include <tqimage.h>
-#ifdef DRAW_OUTLINE
-# include <tqpainter.h>
-#endif
+#include <tqpainter.h>
KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name )
: TQObject( parent, name )
@@ -48,6 +47,25 @@ KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name )
, myLayoutItem( 0 )
, buttonParent( 0 )
{
+ init(node, name);
+}
+
+
+KdmItem::KdmItem( TQWidget *parent, const TQDomNode &node, const char *name )
+ : TQObject( parent, name )
+ , boxManager( 0 )
+ , fixedManager( 0 )
+ , image( 0 )
+ , myWidget( 0 )
+ , myLayoutItem( 0 )
+ , buttonParent( 0 )
+{
+ init(node, name);
+}
+
+void
+KdmItem::init( const TQDomNode &node, const char * )
+{
// Set default layout for every item
currentManager = MNone;
pos.x = pos.y = 0;
@@ -62,7 +80,7 @@ KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name )
state = Snormal;
// The "toplevel" node (the screen) is really just like a fixed node
- if (!parent || !parent->inherits( "KdmItem" )) {
+ if (!parent() || !parent()->inherits( "KdmItem" )) {
setFixedLayout();
return;
}
@@ -87,7 +105,7 @@ KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name )
id = tnode.toElement().attribute( "id", TQString::number( (ulong)this, 16 ) );
// Tell 'parent' to add 'me' to its children
- KdmItem *parentItem = static_cast<KdmItem *>( parent );
+ KdmItem *parentItem = static_cast<KdmItem *>( parent() );
parentItem->addChildItem( this );
}
@@ -195,7 +213,7 @@ KdmItem::setWidget( TQWidget *widget )
if (frame)
frame->setFrameStyle( TQFrame::NoFrame );
- myWidget->setGeometry(area);
+ setGeometry(area, true);
connect( myWidget, TQT_SIGNAL(destroyed()), TQT_SLOT(widgetGone()) );
}
@@ -236,15 +254,21 @@ KdmItem::setGeometry( const TQRect &newGeometry, bool force )
area = newGeometry;
- if (myWidget)
- myWidget->setGeometry( newGeometry );
+ if (myWidget) {
+ TQRect widGeo = newGeometry;
+ if ( widGeo.height() > myWidget->maximumHeight() ) {
+ widGeo.moveTop( widGeo.top() + ( widGeo.height() - myWidget->maximumHeight() ) / 2 );
+ widGeo.setHeight( myWidget->maximumHeight() );
+ }
+ myWidget->setGeometry( widGeo );
+ }
if (myLayoutItem)
myLayoutItem->setGeometry( newGeometry );
// recurr to all boxed children
if (boxManager && !boxManager->isEmpty())
boxManager->update( newGeometry, force );
-
+
// recurr to all fixed children
if (fixedManager && !fixedManager->isEmpty())
fixedManager->update( newGeometry, force );
@@ -258,8 +282,16 @@ KdmItem::paint( TQPainter *p, const TQRect &rect )
if (isHidden())
return;
- if (myWidget || (myLayoutItem && myLayoutItem->widget()))
- return;
+ if (myWidget || (myLayoutItem && myLayoutItem->widget())) {
+ // KListView because it's missing a Q_OBJECT
+ if ( myWidget && myWidget->isA( "KListView" ) ) {
+ TQPixmap copy( myWidget->size() );
+ kdDebug() << myWidget->geometry() << " " << area << " " << myWidget->size() << endl;
+ bitBlt( &copy, TQPoint( 0, 0), p->device(), myWidget->geometry(), Qt::CopyROP );
+ myWidget->setPaletteBackgroundPixmap( copy );
+ }
+ return;
+ }
if (area.intersects( rect )) {
TQRect contentsRect = area.intersect( rect );
@@ -280,6 +312,8 @@ KdmItem::paint( TQPainter *p, const TQRect &rect )
TQValueList<KdmItem *>::Iterator it;
for (it = m_children.begin(); it != m_children.end(); ++it)
(*it)->paint( p, rect );
+
+
}
KdmItem *KdmItem::currentActive = 0;
@@ -287,8 +321,11 @@ KdmItem *KdmItem::currentActive = 0;
void
KdmItem::mouseEvent( int x, int y, bool pressed, bool released )
{
+ if (isShown == ExplicitlyHidden)
+ return;
+
if (buttonParent && buttonParent != this) {
- buttonParent->mouseEvent( x, y, pressed, released );
+ buttonParent->mouseEvent( x, y, pressed, released );
return;
}
@@ -362,7 +399,8 @@ KdmItem::placementHint( const TQRect &parentRect )
w = parentRect.width(),
h = parentRect.height();
- kdDebug() << "KdmItem::placementHint parentRect=" << id << parentRect << " hintedSize=" << hintedSize << endl;
+ kdDebug() << timestamp() << " KdmItem::placementHint parentRect=" << parentRect << " hintedSize=" << hintedSize << endl;
+
// check if width or height are set to "box"
if (pos.wType == DTbox || pos.hType == DTbox) {
if (myLayoutItem || myWidget)
@@ -372,7 +410,7 @@ KdmItem::placementHint( const TQRect &parentRect )
return parentRect;
boxHint = boxManager->sizeHint();
}
- kdDebug() << " => boxHint " << boxHint << endl;
+ kdDebug() << timestamp() << " boxHint " << boxHint << endl;
}
if (pos.xType == DTpixel)
@@ -380,25 +418,25 @@ KdmItem::placementHint( const TQRect &parentRect )
else if (pos.xType == DTnpixel)
x = parentRect.right() - pos.x;
else if (pos.xType == DTpercent)
- x += int( parentRect.width() / 100.0 * pos.x );
+ x += qRound( parentRect.width() / 100.0 * pos.x );
if (pos.yType == DTpixel)
y += pos.y;
else if (pos.yType == DTnpixel)
y = parentRect.bottom() - pos.y;
else if (pos.yType == DTpercent)
- y += int( parentRect.height() / 100.0 * pos.y );
+ y += qRound( parentRect.height() / 100.0 * pos.y );
if (pos.wType == DTpixel)
w = pos.width;
else if (pos.wType == DTnpixel)
w -= pos.width;
else if (pos.wType == DTpercent)
- w = int( parentRect.width() / 100.0 * pos.width );
+ w = qRound( parentRect.width() / 100.0 * pos.width );
else if (pos.wType == DTbox)
w = boxHint.width();
else if (hintedSize.width() > 0)
- w = hintedSize.width();
+ w = hintedSize.width();
else
w = 0;
@@ -407,14 +445,22 @@ KdmItem::placementHint( const TQRect &parentRect )
else if (pos.hType == DTnpixel)
h -= pos.height;
else if (pos.hType == DTpercent)
- h = int( parentRect.height() / 100.0 * pos.height );
+ h = qRound( parentRect.height() / 100.0 * pos.height );
else if (pos.hType == DTbox)
h = boxHint.height();
- else if (hintedSize.height() > 0)
- h = hintedSize.height();
- else
+ else if (hintedSize.height() > 0) {
+ if (w && pos.wType != DTnone)
+ h = (hintedSize.height() * w) / hintedSize.width();
+ else
+ h = hintedSize.height();
+ } else
h = 0;
+ // we choose to take the hinted size, but it's better to listen to the aspect ratio
+ if (pos.wType == DTnone && pos.hType != DTnone && h && w) {
+ w = qRound(float(hintedSize.width() * h) / hintedSize.height());
+ }
+
// defaults to center
int dx = -w / 2, dy = -h / 2;
@@ -430,7 +476,7 @@ KdmItem::placementHint( const TQRect &parentRect )
dx = -w;
}
// KdmItem *p = static_cast<KdmItem*>( parent() );
- kdDebug() << "KdmItem::placementHint " << id << " x=" << x << " dx=" << dx << " w=" << w << " y=" << y << " dy=" << dy << " h=" << h << " " << parentRect << endl;
+ kdDebug() << timestamp() << " placementHint " << this << " x=" << x << " dx=" << dx << " w=" << w << " y=" << y << " dy=" << dy << " h=" << h << " " << parentRect << endl;
y += dy;
x += dx;
@@ -529,4 +575,17 @@ KdmItem::setFixedLayout( const TQDomNode &node )
currentManager = MFixed;
}
+TQWidget *
+KdmItem::parentWidget() const
+{
+ if (myWidget)
+ return myWidget;
+ if (!this->parent())
+ return 0;
+
+ if (parent()->qt_cast("TQWidget"))
+ return (TQWidget*)parent();
+ return ((KdmItem*)parent())->parentWidget();
+}
+
#include "kdmitem.moc"
diff --git a/kdm/kfrontend/themer/kdmitem.h b/kdm/kfrontend/themer/kdmitem.h
index 6a73c889f..98b876977 100644
--- a/kdm/kfrontend/themer/kdmitem.h
+++ b/kdm/kfrontend/themer/kdmitem.h
@@ -90,6 +90,8 @@ public:
* Item constructor and destructor
*/
KdmItem( KdmItem *parent, const TQDomNode &node = TQDomNode(), const char *name = 0 );
+ KdmItem( TQWidget *parent, const TQDomNode &node = TQDomNode(), const char *name = 0 ); // for the root
+
virtual ~KdmItem();
/**
@@ -151,6 +153,7 @@ public:
KdmItem *findNode( const TQString &id ) const;
virtual void setWidget( TQWidget *widget );
+ TQWidget *widget() const { return myWidget; }
virtual void setLayoutItem( TQLayoutItem *item );
virtual void hide( bool force = false );
@@ -160,6 +163,9 @@ public:
bool isExplicitlyHidden() const { return isShown == ExplicitlyHidden; }
TQRect rect() const { return area; }
+ TQWidget *parentWidget() const;
+ TQString getId() const { return id; }
+
signals:
void needUpdate( int x, int y, int w, int h );
void activated( const TQString &id );
@@ -237,6 +243,7 @@ protected:
void parseColor( const TQString &, TQColor & );
void inheritFromButton( KdmItem *button );
+ void init( const TQDomNode &node = TQDomNode(), const char *name = 0 );
TQString itemType, id;
TQValueList<KdmItem *> m_children;
diff --git a/kdm/kfrontend/themer/kdmlabel.cpp b/kdm/kfrontend/themer/kdmlabel.cpp
index 297b7cc48..e83ae9dc7 100644
--- a/kdm/kfrontend/themer/kdmlabel.cpp
+++ b/kdm/kfrontend/themer/kdmlabel.cpp
@@ -19,8 +19,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include <config.h>
#include "kdmlabel.h"
-#include <kgreeter.h>
+#include "kdmconfig.h"
+#include "../kgreeter.h"
#include <kglobal.h>
#include <klocale.h>
@@ -31,6 +33,7 @@
#include <tqpainter.h>
#include <tqfontmetrics.h>
#include <tqtimer.h>
+#include <tqaccel.h>
#include <unistd.h>
#include <sys/utsname.h>
@@ -39,7 +42,7 @@
#endif
KdmLabel::KdmLabel( KdmItem *parent, const TQDomNode &node, const char *name )
- : KdmItem( parent, node, name )
+ : KdmItem( parent, node, name ), myAccel(0)
{
itemType = "label";
@@ -92,21 +95,46 @@ KdmLabel::KdmLabel( KdmItem *parent, const TQDomNode &node, const char *name )
}
}
- // Check if this is a timer label
+ // Check if this is a timer label)
label.isTimer = label.text.find( "%c" ) >= 0;
if (label.isTimer) {
timer = new TQTimer( this );
timer->start( 1000 );
connect( timer, TQT_SIGNAL(timeout()), TQT_SLOT(update()) );
}
- cText = lookupText( label.text );
+ setTextInt( lookupText( label.text ) );
+}
+
+void
+KdmLabel::setTextInt( const TQString &txt)
+{
+ // TODO: catch &&
+ cText = txt;
+ cAccel = txt.find('&');
+ delete myAccel;
+ myAccel = 0;
+ if (cAccel != -1) {
+ cText.remove('&');
+ myAccel = new TQAccel(parentWidget());
+ myAccel->insertItem(ALT + UNICODE_ACCEL + cText.at(cAccel).lower().unicode());
+ connect(myAccel, TQT_SIGNAL(activated(int)), TQT_SLOT(slotAccel()));
+ }
+}
+
+void
+KdmLabel::slotAccel()
+{
+ if (buttonParent)
+ emit activated(buttonParent->getId());
+ else
+ emit activated(id);
}
void
KdmLabel::setText( const TQString &txt )
{
label.text = txt;
- update();
+ setTextInt( lookupText( label.text ) );
}
QSize
@@ -139,7 +167,23 @@ KdmLabel::drawContents( TQPainter *p, const TQRect &/*r*/ )
p->setFont( l->font );
p->setPen( l->color );
//TODO paint clipped (tested but not working..)
- p->drawText( area, AlignLeft | SingleLine, cText );
+ if (cAccel != -1 && (!id.isEmpty() || buttonParent) ) {
+ TQString left = cText.left(cAccel);
+ TQString right = cText.mid(cAccel + 1);
+ p->drawText( area, AlignLeft | SingleLine, left );
+ TQRect tarea = area;
+ TQFontMetrics fm(l->font);
+ tarea.rLeft() += fm.width(left);
+ TQFont f(l->font);
+ f.setUnderline(true);
+ p->setFont ( f );
+ p->drawText( tarea, AlignLeft | SingleLine, TQString(cText.at(cAccel)));
+ tarea.rLeft() += fm.width(cText.at(cAccel));
+ p->setFont( l->font );
+ p->drawText( tarea, AlignLeft | SingleLine, right);
+ } else {
+ p->drawText( area, AlignLeft | SingleLine, cText);
+ }
}
void
@@ -159,7 +203,7 @@ KdmLabel::update()
{
TQString text = lookupText( label.text );
if (text != cText) {
- cText = text;
+ setTextInt(text);
needUpdate();
}
}
@@ -170,18 +214,20 @@ static const struct {
{ "language", I18N_NOOP("Language") },
{ "session", I18N_NOOP("Session Type") },
{ "system", I18N_NOOP("Menu") }, // i18n("Actions");
+ { "admin", I18N_NOOP("&Administration") },
{ "disconnect", I18N_NOOP("Disconnect") },
{ "quit", I18N_NOOP("Quit") },
- { "halt", I18N_NOOP("Power off") },
+ { "halt", I18N_NOOP("Power Off") },
{ "suspend", I18N_NOOP("Suspend") },
{ "reboot", I18N_NOOP("Reboot") },
{ "chooser", I18N_NOOP("XDMCP Chooser") },
{ "config", I18N_NOOP("Configure") },
- { "caps-lock-warning", I18N_NOOP("You have got caps lock on.") },
+ { "caps-lock-warning", I18N_NOOP("Caps Lock is enabled.") },
{ "timed-label", I18N_NOOP("User %s will login in %d seconds") },
{ "welcome-label", I18N_NOOP("Welcome to %h") }, // _greetString
{ "username-label", I18N_NOOP("Username:") },
{ "password-label", I18N_NOOP("Password:") },
+ { "domain-label", I18N_NOOP("Domain:") },
{ "login", I18N_NOOP("Login") }
};
@@ -195,7 +241,7 @@ KdmLabel::lookupStock( const TQString &stock )
if (type == stocks[i].type)
return i18n(stocks[i].text);
- kdDebug() << "Invalid <stock> element. Check your theme!" << endl;
+ kdDebug() << timestamp() << " Invalid <stock> element. Check your theme!" << endl;
return stock;
}
@@ -205,7 +251,6 @@ KdmLabel::lookupText( const TQString &t )
TQString text = t;
text.replace( '_', '&' );
-// text.remove( '_' ); // FIXME add key accels, remove underscores for now
TQMap<TQChar,TQString> m;
struct utsname uts;
diff --git a/kdm/kfrontend/themer/kdmlabel.h b/kdm/kfrontend/themer/kdmlabel.h
index 0770259c0..1ec2f88ec 100644
--- a/kdm/kfrontend/themer/kdmlabel.h
+++ b/kdm/kfrontend/themer/kdmlabel.h
@@ -50,6 +50,7 @@ protected:
// handle switching between normal / active / prelight configurations
virtual void statusChanged();
+public:
struct LabelStruct {
TQString text;
bool isTimer;
@@ -67,6 +68,7 @@ protected:
public slots:
void update();
+ void slotAccel();
private:
/* Method to lookup the caption associated with an item */
@@ -76,6 +78,10 @@ private:
TQString lookupText( const TQString &t );
TQString cText;
+ int cAccel;
+ TQAccel *myAccel;
+
+ void setTextInt(const TQString &);
};
#endif
diff --git a/kdm/kfrontend/themer/kdmlayout.cpp b/kdm/kfrontend/themer/kdmlayout.cpp
index 00ca693ae..b17d2e7b7 100644
--- a/kdm/kfrontend/themer/kdmlayout.cpp
+++ b/kdm/kfrontend/themer/kdmlayout.cpp
@@ -20,6 +20,7 @@
*/
#include "kdmlayout.h"
+#include "kdmconfig.h"
#include "kdmitem.h"
#include <kdebug.h>
@@ -35,11 +36,11 @@ KdmLayoutFixed::KdmLayoutFixed( const TQDomNode &/*node*/ )
void
KdmLayoutFixed::update( const TQRect &parentGeometry, bool force )
{
- kdDebug() << "KdmLayoutFixed::update " << parentGeometry << endl;
+ kdDebug() << timestamp() << " KdmLayoutFixed::update " << parentGeometry << endl;
// I can't layout children if the parent rectangle is not valid
if (parentGeometry.width() < 0 || parentGeometry.height() < 0) {
- kdDebug() << "invalid\n";
+ kdDebug() << timestamp() << " invalid\n";
return;
}
// For each child in list I ask their hinted size and set it!
@@ -102,7 +103,7 @@ KdmLayoutBox::update( const TQRect &parentGeometry, bool force )
childrenRect.setTop( childrenRect.top() + height + box.spacing );
} else {
TQRect temp( childrenRect.left(), childrenRect.top(), width, childrenRect.height() );
- kdDebug() << "placement " << *it << " " << temp << " " << (*it)->placementHint( temp ) << endl;
+ kdDebug() << timestamp() << " placement " << *it << " " << temp << " " << (*it)->placementHint( temp ) << endl;
temp = (*it)->placementHint( temp );
(*it)->setGeometry( temp, force );
childrenRect.setLeft( childrenRect.left() + width + box.spacing );
@@ -125,7 +126,7 @@ KdmLayoutBox::update( const TQRect &parentGeometry, bool force )
kdDebug() << this << " placementHint " << *it << " " << temp << " " << itemRect << endl;
temp.setWidth( itemRect.width() );
childrenRect.setLeft( childrenRect.left() + itemRect.size().width() + box.spacing );
- kdDebug() << "childrenRect after " << *it << " " << childrenRect << endl;
+ kdDebug() << timestamp() << " childrenRect after " << *it << " " << childrenRect << endl;
}
itemRect = (*it)->placementHint( temp );
kdDebug() << this << " placementHint2 " << *it << " " << temp << " " << itemRect << endl;
diff --git a/kdm/kfrontend/themer/kdmpixmap.cpp b/kdm/kfrontend/themer/kdmpixmap.cpp
index 07077e4a1..f18194f53 100644
--- a/kdm/kfrontend/themer/kdmpixmap.cpp
+++ b/kdm/kfrontend/themer/kdmpixmap.cpp
@@ -22,6 +22,7 @@
#include <config.h>
#include "kdmpixmap.h"
+#include <kdmconfig.h>
#include <kimageeffect.h>
#ifdef HAVE_LIBART
@@ -29,6 +30,7 @@
#endif
#include <kdebug.h>
+#include <kstandarddirs.h>
#include <tqpainter.h>
#include <tqpixmap.h>
@@ -58,21 +60,28 @@ KdmPixmap::KdmPixmap( KdmItem *parent, const TQDomNode &node, const char *name )
TQString tagName = el.tagName();
if (tagName == "normal") {
- loadPixmap( el.attribute( "file", "" ), pixmap.normal.pixmap, pixmap.normal.fullpath );
+ pixmap.normal.fullpath = fullPath( el.attribute( "file", "" ) );
parseColor( el.attribute( "tint", "#ffffff" ), pixmap.normal.tint );
pixmap.normal.alpha = el.attribute( "alpha", "1.0" ).toFloat();
} else if (tagName == "active") {
pixmap.active.present = true;
- loadPixmap( el.attribute( "file", "" ), pixmap.active.pixmap, pixmap.active.fullpath );
+ pixmap.active.fullpath = fullPath( el.attribute( "file", "" ) );
parseColor( el.attribute( "tint", "#ffffff" ), pixmap.active.tint );
pixmap.active.alpha = el.attribute( "alpha", "1.0" ).toFloat();
} else if (tagName == "prelight") {
pixmap.prelight.present = true;
- loadPixmap( el.attribute( "file", "" ), pixmap.prelight.pixmap, pixmap.prelight.fullpath );
+ pixmap.prelight.fullpath = fullPath(el.attribute( "file", "" ) );
parseColor( el.attribute( "tint", "#ffffff" ), pixmap.prelight.tint );
pixmap.prelight.alpha = el.attribute( "alpha", "1.0" ).toFloat();
}
}
+
+ // look if we have to have the aspect ratio ready
+ if (((pos.wType == DTnone && pos.hType != DTnone) ||
+ (pos.wType != DTnone && pos.hType == DTnone) ||
+ (pos.wType == DTnone && pos.hType == DTnone)) &&
+ !pixmap.normal.fullpath.endsWith( ".svg" ))
+ loadPixmap( &pixmap.normal );
}
QSize
@@ -100,19 +109,16 @@ KdmPixmap::setGeometry( const TQRect &newGeometry, bool force )
}
-void
-KdmPixmap::loadPixmap( const TQString &fileName, TQPixmap &map, TQString &fullName )
+TQString
+KdmPixmap::fullPath( const TQString &fileName)
{
- if (fileName.isEmpty())
- return;
+ if (fileName.isEmpty())
+ return TQString::null;
- fullName = fileName;
+ TQString fullName = fileName;
if (fullName.at( 0 ) != '/')
fullName = baseDir() + "/" + fileName;
-
- if (!fullName.endsWith( ".svg" )) // we delay it for svgs
- if (!map.load( fullName ))
- fullName = TQString::null;
+ return fullName;
}
void
@@ -140,6 +146,25 @@ KdmPixmap::renderSvg( PixmapStruct::PixmapClass *pClass, const TQRect &area )
}
void
+KdmPixmap::loadPixmap( PixmapStruct::PixmapClass *pClass )
+{
+ TQString fullpath = pClass->fullpath;
+
+ kdDebug() << timestamp() << " load " << fullpath << endl;
+ int index = fullpath.findRev('.');
+ TQString ext = fullpath.right(fullpath.length() - index);
+ fullpath = fullpath.left(index);
+ kdDebug() << timestamp() << " ext " << ext << " " << fullpath << endl;
+ TQString testpath = TQString("-%1x%2").arg(area.width()).arg(area.height()) + ext;
+ kdDebug() << timestamp() << " testing for " << fullpath + testpath << endl;
+ if (KStandardDirs::exists(fullpath + testpath))
+ pClass->pixmap.load(fullpath + testpath);
+ else
+ pClass->pixmap.load( fullpath + ext );
+ kdDebug() << timestamp() << " done\n";
+}
+
+void
KdmPixmap::drawContents( TQPainter *p, const TQRect &r )
{
// choose the correct pixmap class
@@ -149,12 +174,20 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r )
if (state == Sprelight && pixmap.prelight.present)
pClass = &pixmap.prelight;
+ kdDebug() << "draw " << id << " " << pClass->pixmap.isNull() << endl;
+
if (pClass->pixmap.isNull()) {
- if (pClass->fullpath.isEmpty()) // if neither is set, we're empty
+
+ if (pClass->fullpath.isEmpty()) // if neither is set, we're empty
return;
-
- kdDebug() << "renderSVG\n";
- renderSvg( pClass, area );
+
+ if (!pClass->fullpath.endsWith( ".svg" ) ) {
+ loadPixmap(pClass);
+ } else {
+ kdDebug() << timestamp() << " renderSVG\n";
+ renderSvg( pClass, area );
+ kdDebug() << timestamp() << " done\n";
+ }
}
int px = area.left() + r.left();
@@ -176,25 +209,37 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r )
if (pClass->readyPixmap.isNull()) {
- TQImage scaledImage;
+
+ bool haveTint = pClass->tint.rgb() != 0xFFFFFF;
+ bool haveAlpha = pClass->alpha < 1.0;
+ TQImage scaledImage;
+
// use the loaded pixmap or a scaled version if needed
+ kdDebug() << timestamp() << " prepare readyPixmap " << pClass->fullpath << " " << area.size() << " " << pClass->pixmap.size() << endl;
if (area.size() != pClass->pixmap.size()) {
if (pClass->fullpath.endsWith( ".svg" )) {
- kdDebug() << "renderSVG\n";
+ kdDebug() << timestamp() << " renderSVG\n";
renderSvg( pClass, area );
scaledImage = pClass->pixmap.convertToImage();
} else {
- kdDebug() << "convertFromImage\n";
+ kdDebug() << timestamp() << " convertFromImage smoothscale\n";
TQImage tempImage = pClass->pixmap.convertToImage();
+ kdDebug() << timestamp() << " convertToImage done\n";
scaledImage = tempImage.smoothScale( area.width(), area.height() );
+ kdDebug() << timestamp() << " done\n";
}
- } else
+ } else {
+ if (haveTint || haveAlpha)
+ {
scaledImage = pClass->pixmap.convertToImage();
-
- bool haveTint = pClass->tint.rgb() != 0xFFFFFF;
- bool haveAlpha = pClass->alpha < 1.0;
+ // enforce rgba values for the later
+ scaledImage = scaledImage.convertDepth( 32 );
+ }
+ else
+ pClass->readyPixmap = pClass->pixmap;
+ }
if (haveTint || haveAlpha) {
// blend image(pix) with the given tint
@@ -221,9 +266,12 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r )
}
- pClass->readyPixmap.convertFromImage( scaledImage );
+ if (!scaledImage.isNull()) {
+ kdDebug() << timestamp() << " convertFromImage " << id << " " << area << endl;
+ pClass->readyPixmap.convertFromImage( scaledImage );
+ }
}
- // kdDebug() << "Pixmap::drawContents " << pClass->readyPixmap.size() << " " << px << " " << py << " " << sx << " " << sy << " " << sw << " " << sh << endl;
+ kdDebug() << timestamp() << " Pixmap::drawContents " << pClass->readyPixmap.size() << " " << px << " " << py << " " << sx << " " << sy << " " << sw << " " << sh << endl;
p->drawPixmap( px, py, pClass->readyPixmap, sx, sy, sw, sh );
}
diff --git a/kdm/kfrontend/themer/kdmpixmap.h b/kdm/kfrontend/themer/kdmpixmap.h
index 479ef0f8d..92d4895d0 100644
--- a/kdm/kfrontend/themer/kdmpixmap.h
+++ b/kdm/kfrontend/themer/kdmpixmap.h
@@ -61,9 +61,10 @@ protected:
} pixmap;
private:
- // Method to load the pixmap given by the theme
- void loadPixmap( const TQString &fileName, TQPixmap &p, TQString &path );
+ // Method to load the pixmap path given by the theme
+ TQString fullPath( const TQString &fileName );
void renderSvg( PixmapStruct::PixmapClass *pClass, const TQRect &area );
+ void loadPixmap( PixmapStruct::PixmapClass *pClass );
};
#endif
diff --git a/kdm/kfrontend/themer/kdmrect.cpp b/kdm/kfrontend/themer/kdmrect.cpp
index 961809a37..1d854d213 100644
--- a/kdm/kfrontend/themer/kdmrect.cpp
+++ b/kdm/kfrontend/themer/kdmrect.cpp
@@ -33,6 +33,18 @@
KdmRect::KdmRect( KdmItem *parent, const TQDomNode &node, const char *name )
: KdmItem( parent, node, name )
{
+ init( node, name );
+}
+
+KdmRect::KdmRect( TQWidget *parent, const TQDomNode &node, const char *name )
+ : KdmItem( parent, node, name )
+{
+ init( node, name );
+}
+
+void
+KdmRect::init( const TQDomNode &node, const char * )
+{
itemType = "rect";
// Set default values for rect (note: strings are already Null)
@@ -137,13 +149,6 @@ KdmRect::recursiveSetAttribs( TQLayoutItem *li )
}
void
-KdmRect::setWidget( TQWidget *widget )
-{
- KdmItem::setWidget( widget );
- setAttribs( widget );
-}
-
-void
KdmRect::setLayoutItem( TQLayoutItem *item )
{
KdmItem::setLayoutItem( item );
@@ -151,4 +156,17 @@ KdmRect::setLayoutItem( TQLayoutItem *item )
}
*/
+void
+KdmRect::setWidget( TQWidget *widget )
+{
+ if ( rect.normal.color.isValid() && widget )
+ {
+ TQPalette p = widget->palette();
+ p.setColor( TQPalette::Normal, TQColorGroup::Text, rect.normal.color );
+ widget->setPalette(p);
+ }
+ KdmItem::setWidget( widget );
+ //setAttribs( widget );
+}
+
#include "kdmrect.moc"
diff --git a/kdm/kfrontend/themer/kdmrect.h b/kdm/kfrontend/themer/kdmrect.h
index 7e4776233..a505e1921 100644
--- a/kdm/kfrontend/themer/kdmrect.h
+++ b/kdm/kfrontend/themer/kdmrect.h
@@ -36,6 +36,7 @@ class KdmRect : public KdmItem {
public:
KdmRect( KdmItem *parent, const TQDomNode &node, const char *name = 0 );
+ KdmRect( TQWidget *parent, const TQDomNode &node, const char *name = 0 );
protected:
// draw the rect
@@ -54,8 +55,9 @@ protected:
bool hasBorder;
} rect;
-// virtual void setWidget( TQWidget *widget );
+ virtual void setWidget( TQWidget *widget );
// virtual void setLayoutItem( TQLayoutItem *item );
+ void init( const TQDomNode &node, const char *name );
private:
void setAttribs( TQWidget *widget );
diff --git a/kdm/kfrontend/themer/kdmthemer.cpp b/kdm/kfrontend/themer/kdmthemer.cpp
index aca43e45d..9e6db33db 100644
--- a/kdm/kfrontend/themer/kdmthemer.cpp
+++ b/kdm/kfrontend/themer/kdmthemer.cpp
@@ -36,11 +36,13 @@
#include <tqfile.h>
#include <tqfileinfo.h>
-//#include <tqtimer.h> // animation timer - TODO
+#include <tqtimer.h> // animation timer - TODO
#include <tqobjectlist.h>
#include <tqpainter.h>
#include <tqwidget.h>
#include <tqregion.h>
+#include <tqlineedit.h>
+#include <tqapplication.h>
#include <unistd.h>
@@ -72,7 +74,8 @@ KdmThemer::KdmThemer( const TQString &_filename, const TQString &mode, TQWidget
return;
}
// Set the root (screen) item
- rootItem = new KdmRect( 0, TQDomNode(), "kdm root" );
+ rootItem = new KdmRect( parent, TQDomNode(), "kdm root" );
+
connect( rootItem, TQT_SIGNAL(needUpdate( int, int, int, int )),
widget(), TQT_SLOT(update( int, int, int, int )) );
@@ -82,6 +85,9 @@ KdmThemer::KdmThemer( const TQString &_filename, const TQString &mode, TQWidget
generateItems( rootItem );
connect( rootItem, TQT_SIGNAL(activated( const TQString & )), TQT_SIGNAL(activated( const TQString & )) );
+ connect( rootItem, TQT_SIGNAL(activated( const TQString & )), TQT_SLOT(slotActivated( const TQString & )) );
+
+ TQTimer::singleShot(800, this, TQT_SLOT(slotPaintRoot()));
/* *TODO*
// Animation timer
@@ -151,7 +157,7 @@ KdmThemer::widgetEvent( TQEvent *e )
case TQEvent::Paint:
{
TQRect paintRect = static_cast<TQPaintEvent *>(e)->rect();
- kdDebug() << "paint on: " << paintRect << endl;
+ kdDebug() << timestamp() << " paint on: " << paintRect << endl;
if (!backBuffer)
backBuffer = new TQPixmap( widget()->size() );
@@ -195,7 +201,7 @@ KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node )
// Get its tag, and check it's correct ("greeter")
if (theme.tagName() != "greeter") {
- kdDebug() << "This does not seem to be a correct theme file." << endl;
+ kdDebug() << timestamp() << " This does not seem to be a correct theme file." << endl;
return;
}
// Get the list of child nodes
@@ -214,6 +220,13 @@ KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node )
if (tagName == "item") {
if (!willDisplay( subnode ))
continue;
+ TQString id = el.attribute("id");
+ if (id.startsWith("plugin-specific-")) {
+ id = id.mid(strlen("plugin-specific-"));
+ if (!_pluginsLogin.contains(id))
+ continue;
+ }
+
// It's a new item. Draw it
TQString type = el.attribute( "type" );
@@ -225,13 +238,11 @@ KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node )
newItem = new KdmPixmap( parent, subnode );
else if (type == "rect")
newItem = new KdmRect( parent, subnode );
- else if (type == "entry") {
+ else if (type == "entry" || type == "list") {
newItem = new KdmRect( parent, subnode );
newItem->setType( type );
}
// newItem = new KdmEntry( parent, subnode );
- //else if (type=="list")
- // newItem = new KdmList( parent, subnode );
else if (type == "svg")
newItem = new KdmPixmap( parent, subnode );
if (newItem) {
@@ -287,6 +298,11 @@ bool KdmThemer::willDisplay( const TQDomNode &node )
#endif
if (type == "halt" || type == "reboot")
return _allowShutdown != SHUT_NONE;
+ else if (type == "userlist")
+ return _userList;
+ else if ( type == "!userlist" )
+ return !_userList;
+
// if (type == "system")
// return true;
@@ -301,7 +317,7 @@ KdmThemer::showStructure( TQObject *obj )
const TQObjectList *wlist = obj->children();
static int counter = 0;
if (counter == 0)
- kdDebug() << "\n\n<======= Widget tree =================" << endl;
+ kdDebug() << timestamp() << " \n\n<======= Widget tree =================" << endl;
if (wlist) {
counter++;
TQObjectListIterator it( *wlist );
@@ -323,7 +339,46 @@ KdmThemer::showStructure( TQObject *obj )
counter--;
}
if (counter == 0)
- kdDebug() << "\n\n<======= Widget tree =================\n\n" << endl;
+ kdDebug() << timestamp() << " \n\n<======= Widget tree =================\n\n" << endl;
+}
+
+void
+KdmThemer::slotActivated( const TQString &id )
+{
+ TQString toactivate;
+ if (id == "username-label")
+ toactivate = "user-entry";
+ else if (id == "password-label")
+ toactivate = "pw-entry";
+ else
+ return;
+
+ KdmItem *item = findNode(toactivate);
+ if (!item || !item->widget())
+ return;
+
+ item->widget()->setFocus();
+ TQLineEdit *le = (TQLineEdit*)item->widget()->qt_cast("TQLineEdit");
+ if (le)
+ le->selectAll();
+}
+
+void
+KdmThemer::slotPaintRoot()
+{
+ KdmItem *back_item = findNode("background");
+ if (!back_item)
+ return;
+
+ TQRect screen = TQApplication::desktop()->screenGeometry(0);
+ TQPixmap pm(screen.size());
+
+ TQPainter painter( &pm, true );
+ back_item->paint( &painter, back_item->rect());
+ painter.end();
+
+ TQApplication::desktop()->screen()->setErasePixmap(pm);
+ TQApplication::desktop()->screen()->erase();
}
#include "kdmthemer.moc"
diff --git a/kdm/kfrontend/themer/kdmthemer.h b/kdm/kfrontend/themer/kdmthemer.h
index 6bf6af00d..6dc2318dd 100644
--- a/kdm/kfrontend/themer/kdmthemer.h
+++ b/kdm/kfrontend/themer/kdmthemer.h
@@ -80,6 +80,10 @@ public:
signals:
void activated( const TQString &id );
+protected slots:
+ void slotActivated( const TQString &id );
+ void slotPaintRoot();
+
private:
/*
* Our display mode (e.g. console, remote, ...)