diff options
Diffstat (limited to 'sessionapplet')
-rw-r--r-- | sessionapplet/Makefile.am | 15 | ||||
-rw-r--r-- | sessionapplet/dmctl.cpp | 322 | ||||
-rw-r--r-- | sessionapplet/dmctl.h | 91 | ||||
-rw-r--r-- | sessionapplet/usermanager.cpp | 281 | ||||
-rw-r--r-- | sessionapplet/usermanager.desktop | 8 | ||||
-rw-r--r-- | sessionapplet/usermanager.h | 78 | ||||
-rw-r--r-- | sessionapplet/usermanager.lsm | 16 |
7 files changed, 811 insertions, 0 deletions
diff --git a/sessionapplet/Makefile.am b/sessionapplet/Makefile.am new file mode 100644 index 0000000..4472c36 --- /dev/null +++ b/sessionapplet/Makefile.am @@ -0,0 +1,15 @@ +INCLUDES= $(all_includes) +METASOURCES = AUTO + +lib_LTLIBRARIES = usermanager_panelapplet.la + +usermanager_panelapplet_la_SOURCES = usermanager.cpp dmctl.cpp +usermanager_panelapplet_la_LDFLAGS = -module -avoid-version $(all_libraries) +usermanager_panelapplet_la_LIBADD = $(LIB_KDEUI) + +usermanager_DATA = usermanager.desktop +usermanagerdir = $(kde_datadir)/kicker/applets + +messages: rc.cpp + $(EXTRACTRC) `find . -name \*.ui -o -name \*.rc` > rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/usermanager.pot diff --git a/sessionapplet/dmctl.cpp b/sessionapplet/dmctl.cpp new file mode 100644 index 0000000..a6d5bf9 --- /dev/null +++ b/sessionapplet/dmctl.cpp @@ -0,0 +1,322 @@ +/* + Copyright (C) 2004 Oswald Buddenhagen <ossi@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the Lesser 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 Lesser GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "dmctl.h" + +#ifdef Q_WS_X11 + +#include <klocale.h> +#include <dcopclient.h> + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> +#include <stdlib.h> +#include <fcntl.h> +#include <errno.h> + +static enum { Dunno, NoDM, NewKDM, OldKDM/*, GDM*/ } DMType = Dunno; +static const char *ctl, *dpy; + +DM::DM() : fd( -1 ) +{ + char *ptr; + struct sockaddr_un sa; + + if (DMType == Dunno) { + if (!(dpy = ::getenv( "DISPLAY" ))) + DMType = NoDM; + else if ((ctl = ::getenv( "DM_CONTROL" ))) + DMType = NewKDM; + else if ((ctl = ::getenv( "XDM_MANAGED" )) && ctl[0] == '/') + DMType = OldKDM; + else + DMType = NoDM; + } + switch (DMType) { + default: + return; + case NewKDM: + if ((fd = ::socket( PF_UNIX, SOCK_STREAM, 0 )) < 0) + return; + sa.sun_family = AF_UNIX; + if ((ptr = strchr( dpy, ':' ))) + ptr = strchr( ptr, '.' ); + snprintf( sa.sun_path, sizeof(sa.sun_path), + "%s/dmctl-%.*s/socket", ctl, ptr ? ptr - dpy : 512, dpy ); + if (::connect( fd, (struct sockaddr *)&sa, sizeof(sa) )) { + ::close( fd ); + fd = -1; + } + break; + case OldKDM: + { + QString tf( ctl ); + tf.truncate( tf.find( ',' ) ); + fd = ::open( tf.latin1(), O_WRONLY ); + } + break; + } +} + +DM::~DM() +{ + if (fd >= 0) + close( fd ); +} + +bool +DM::exec( const char *cmd ) +{ + QCString buf; + + return exec( cmd, buf ); +} + +/** + * Execute a KDM remote control command. + * @param cmd the command to execute. FIXME: undocumented yet. + * @param ret the result buffer. + * @return result: + * @li If true, the command was successfully executed. + * @p ret might contain addional results. + * @li If false and @p ret is empty, a communication error occurred + * (most probably KDM is not running). + * @li If false and @p ret is non-empty, it contains the error message + * from KDM. + */ +bool +DM::exec( const char *cmd, QCString &buf ) +{ + bool ret = false; + int tl; + unsigned len = 0; + + if (fd < 0) + goto busted; + + if (::write( fd, cmd, (tl = strlen( cmd )) ) != tl) { + bust: + ::close( fd ); + fd = -1; + busted: + buf.resize( 0 ); + return false; + } + if (DMType == OldKDM) { + buf.resize( 0 ); + return true; + } + for (;;) { + if (buf.size() < 128) + buf.resize( 128 ); + else if (buf.size() < len * 2) + buf.resize( len * 2 ); + if ((tl = ::read( fd, buf.data() + len, buf.size() - len)) <= 0) { + if (tl < 0 && errno == EINTR) + continue; + goto bust; + } + len += tl; + if (buf[len - 1] == '\n') { + buf[len - 1] = 0; + if (len > 2 && buf[0] == 'o' && buf[1] == 'k' && buf[2] < 32) + ret = true; + break; + } + } + return ret; +} + +bool +DM::canShutdown() +{ + if (DMType == OldKDM) + return strstr( ctl, ",maysd" ) != 0; + + QCString re; + + return exec( "caps\n", re ) && re.find( "\tshutdown" ) >= 0; +} + +void +DM::shutdown( KApplication::ShutdownType shutdownType, + KApplication::ShutdownMode shutdownMode, + const QString &bootOption ) +{ + if (!bootOption.isEmpty() && DMType != NewKDM) + return; + + if (shutdownType != KApplication::ShutdownTypeNone) { + QCString cmd( "shutdown\t" ); + cmd.append( shutdownType == KApplication::ShutdownTypeReboot ? + "reboot\t" : "halt\t" ); + if (!bootOption.isNull()) + cmd.append( "=" ).append( bootOption.local8Bit() ).append( "\t" ); + cmd.append( shutdownMode == KApplication::ShutdownModeInteractive ? + "ask\n" : + shutdownMode == KApplication::ShutdownModeForceNow ? + "forcenow\n" : + shutdownMode == KApplication::ShutdownModeTryNow ? + "trynow\n" : "schedule\n" ); + exec( cmd.data() ); + } +} + +bool +DM::bootOptions( QStringList &opts, int &defopt, int ¤t ) +{ + if (DMType != NewKDM) + return false; + + QCString re; + if (!exec( "listbootoptions\n", re )) + return false; + + opts = QStringList::split( '\t', QString::fromLocal8Bit( re.data() ) ); + if (opts.size() < 4) + return false; + + bool ok; + defopt = opts[2].toInt( &ok ); + if (!ok) + return false; + current = opts[3].toInt( &ok ); + if (!ok) + return false; + + opts = QStringList::split( ' ', opts[1] ); + for (QStringList::Iterator it = opts.begin(); it != opts.end(); ++it) + (*it).replace( "\\s", " " ); + + return true; +} + +void +DM::setLock( bool on ) +{ + exec( on ? "lock\n" : "unlock\n" ); +} + +bool +DM::isSwitchable() +{ + if (DMType == OldKDM) + return dpy[0] == ':'; + + QCString re; + + return exec( "caps\n", re ) && re.find( "\tlocal" ) >= 0; +} + +int +DM::numReserve() +{ + if (DMType == OldKDM) + return strstr( ctl, ",rsvd" ) ? 1 : -1; + + QCString re; + int p; + + if (!(exec( "caps\n", re ) && (p = re.find( "\treserve " )) >= 0)) + return -1; + return atoi( re.data() + p + 9 ); +} + +void +DM::startReserve() +{ + exec("reserve\n"); +} + +bool +DM::localSessions( SessList &list ) +{ + if (DMType == OldKDM) + return false; + + QCString re; + + if (!exec( "list\talllocal\n", re )) + return false; + QStringList sess = QStringList::split( QChar('\t'), re.data() + 3 ); + for (QStringList::ConstIterator it = sess.begin(); it != sess.end(); ++it) { + QStringList ts = QStringList::split( QChar(','), *it, true ); + SessEnt se; + se.display = ts[0]; + if (ts[1][0] == '@') + se.from = ts[1].mid( 1 ), se.vt = 0; + else + se.vt = ts[1].mid( 2 ).toInt(); + se.user = ts[2]; + se.session = ts[3]; + se.self = (ts[4].find( '*' ) >= 0); + se.tty = (ts[4].find( 't' ) >= 0); + list.append( se ); + } + return true; +} + +void +DM::sess2Str2( const SessEnt &se, QString &user, QString &loc ) +{ + if (se.tty) { + user = i18n("user: ...", "%1: TTY login").arg( se.user ); + loc = se.vt ? QString("vt%1").arg( se.vt ) : se.display ; + } else { + user = + se.user.isEmpty() ? + se.session.isEmpty() ? + i18n("Unused") : + se.session == "<remote>" ? + i18n("X login on remote host") : + i18n("... host", "X login on %1").arg( se.session ) : + i18n("user: session type", "%1: %2") + .arg( se.user ).arg( se.session ); + loc = + se.vt ? + QString("%1, vt%2").arg( se.display ).arg( se.vt ) : + se.display; + } +} + +QString +DM::sess2Str( const SessEnt &se ) +{ + QString user, loc; + + sess2Str2( se, user, loc ); + return i18n("session (location)", "%1 (%2)").arg( user ).arg( loc ); +} + +bool +DM::switchVT( int vt ) +{ + return exec( QString("activate\tvt%1\n").arg(vt).latin1() ); +} + +void +DM::lockSwitchVT( int vt ) +{ + if (switchVT( vt )) + kapp->dcopClient()->send( "kdesktop", "KScreensaverIface", "lock()", "" ); +} + +#endif // Q_WS_X11 diff --git a/sessionapplet/dmctl.h b/sessionapplet/dmctl.h new file mode 100644 index 0000000..bc58fcb --- /dev/null +++ b/sessionapplet/dmctl.h @@ -0,0 +1,91 @@ +/* + Copyright (C) 2004,2005 Oswald Buddenhagen <ossi@kde.org> + Copyright (C) 2005 Stephan Kulow <coolo@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the Lesser 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 Lesser GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef DMCTL_H +#define DMCTL_H + +#include <kapplication.h> + +struct SessEnt { + QString display, from, user, session; + int vt; + bool self:1, tty:1; +}; + +typedef QValueList<SessEnt> SessList; + +class DM { + +#ifdef Q_WS_X11 + +public: + DM(); + ~DM(); + + bool canShutdown(); + void shutdown( KApplication::ShutdownType shutdownType, + KApplication::ShutdownMode shutdownMode, + const QString &bootOption = QString::null ); + + void setLock( bool on ); + + bool isSwitchable(); + int numReserve(); + void startReserve(); + bool localSessions( SessList &list ); + bool switchVT( int vt ); + void lockSwitchVT( int vt ); + + bool bootOptions( QStringList &opts, int &dflt, int &curr ); + + static QString sess2Str( const SessEnt &se ); + static void sess2Str2( const SessEnt &se, QString &user, QString &loc ); + +private: + int fd; + + bool exec( const char *cmd, QCString &ret ); + bool exec( const char *cmd ); + +#else // Q_WS_X11 + +public: + DM() {} + + bool canShutdown() { return false; } + void shutdown( KApplication::ShutdownType shutdownType, + KApplication::ShutdownMode shutdownMode, + const QString &bootOption = QString::null ) {} + + void setLock( bool ) {} + + bool isSwitchable() { return false; } + int numReserve() { return -1; } + void startReserve() {} + bool localSessions( SessList &list ) { return false; } + void switchVT( int vt ) {} + + bool bootOptions( QStringList &opts, int &dflt, int &curr ); + +#endif // Q_WS_X11 + +}; // class DM + +#endif // DMCTL_H diff --git a/sessionapplet/usermanager.cpp b/sessionapplet/usermanager.cpp new file mode 100644 index 0000000..faf491f --- /dev/null +++ b/sessionapplet/usermanager.cpp @@ -0,0 +1,281 @@ +/*************************************************************************** + * Copyright (C) 2005 by Thomas Lübking * + * thomas.luebking@web.de * + * * + * 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 <stdlib.h> +#include <kmenubar.h> +// #include <qlabel.h> +#include <qlayout.h> +#include <qpopupmenu.h> +#include <dcopclient.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kconfig.h> +#include <ksimpleconfig.h> +#include <kapplication.h> +#include <kdeversion.h> +#include <kmessagebox.h> +#include <kservice.h> +#include <kstandarddirs.h> +#include "dmctl.h" +#include "usermanager.h" + +#define _ICONSET_(i) KGlobal::iconLoader()->loadIconSet(i, KIcon::Small, 0, false) + + +UserManager::UserManager(const QString& configFile, Type type, int actions, QWidget *parent, const char *name) + : KPanelApplet(configFile, type, actions, parent, name) +{ + + // Get the current application configuration handle + ksConfig = config(); + lockIcon = _ICONSET_("lock"); + fileSaveIcon = _ICONSET_("filesave"); + exitIcon = _ICONSET_("exit"); + setFixedWidth(600); + + menu = new KMenuBar(this); + menu->setTopLevelMenu(false); + menu->setFrameShape ( QFrame::NoFrame ); + menu->setMargin ( 0 ); + menu->setLineWidth ( 0 ); + + // sessions + sessionPopup = new QPopupMenu(this); + menu->insertItem ( getenv("USER"), sessionPopup, 0); + connect( sessionPopup, SIGNAL(aboutToShow()), SLOT(slotPopulateSessions()) ); + connect( sessionPopup, SIGNAL(activated(int)), SLOT(slotSessionActivated(int)) ); + + // languages + langPopup = new QPopupMenu(this); + + KConfigBase *config = KGlobal::config(); + config->setGroup("Locale"); + langList = config->readListEntry ("Language", ':'); +// QString flag( locate( "locale", QString::fromLatin1( "l10n/%1/flag.png" ).arg(langList[0]) ) ); +// langLabel = new QLabel(this); +// langLabel->setPixmap(_ICONSET_(flag).pixmap()); + + menu->insertItem ( '[' + langList[0].section('_',0,0) + ']', langPopup, 1 ); + menu->connectItem ( 1, this, SLOT(slotPopulateLanguages()) ); + connect( langPopup, SIGNAL(aboutToShow()), SLOT(slotPopulateLanguages()) ); + connect( langPopup, SIGNAL(activated(int)), SLOT(slotLanguageActivated(int)) ); + + menu->adjustSize(); + + setFixedWidth(menu->width()+5); + + mainView = menu; + menu->move(menu->mapToParent(QPoint(0,0)).x(),0); + menu->show(); +} + +UserManager::~UserManager() +{ +} + +int UserManager::widthForHeight(int) const +{ + return menu->width(); +} + +int UserManager::heightForWidth(int) const +{ + return menu->height(); +} + +void UserManager::about() +{ + KMessageBox::information(0, i18n("This is an about box")); +} + +void UserManager::lock() +{ + QCString appname( "kdesktop" ); +// if ( kicker_screen_number ) +// appname.sprintf("kdesktop-screen-%d", kicker_screen_number); + kapp->dcopClient()->send(appname, "KScreensaverIface", "lock()", ""); +} + +void UserManager::logout() +{ + kapp->requestShutDown(); +} + + +void UserManager::slotPopulateLanguages() +{ + langPopup->clear(); + KConfig *config = new KConfig("kdeglobals"); + config->setGroup("Locale"); + langList = config->readListEntry ("Language", ':'); + int i = 0; + for ( QStringList::ConstIterator it = langList.begin(); + it != langList.end(); ++it ) + { + KConfig entry(locate( "locale", QString::fromLatin1( "%1/entry.desktop" ).arg(*it) )); + entry.setGroup("KCM Locale"); + QString name = entry.readEntry("Name", i18n("without name")); + + QString flag( locate( "locale", QString::fromLatin1( "%1/flag.png" ).arg(*it) ) ); + langPopup->insertItem( _ICONSET_(flag), name, i ); + i++; + } +// langPopup->popup(langLabel->mapToGlobal(QPoint(0,height()))); +} + +void UserManager::slotLanguageActivated( int i ) +{ + if (i == 0) + return; // no change, no action + menu->changeItem ( 1, '[' + langList[i].section('_',0,0) + ']'/**langPopup->pixmap(i)*/ ); +// langLabel->setPixmap(*langPopup->pixmap(i)); + KConfig *config = new KConfig("kdeglobals"); + config->setGroup("Locale"); + QString tmp = langList[i]; + langList.remove(langList.at(i)); + langList.prepend(tmp); + config->writeEntry ("Language", langList, ':'); + config->sync(); +// KService::rebuildKSycoca(this); + delete config; +} + +void UserManager::slotPopulateSessions() +{ + int p = 0; + DM dm; + + sessionPopup->clear(); + // lock + if (kapp->authorize("lock_screen")) + { + sessionPopup->insertItem(lockIcon, i18n("Lock Session"), 102); + } + sessionPopup->insertSeparator(); + // switch + if (kapp->authorize("start_new_session") && (p = dm.numReserve()) >= 0) + { + if (kapp->authorize("lock_screen")) + sessionPopup->insertItem(/*_ICONSET_("lockfork"),*/ i18n("Lock&&Load Session..."), 100 ); + sessionPopup->insertItem(_ICONSET_("fork"), i18n("New Session..."), 101 ); + if (!p) { + sessionPopup->setItemEnabled( 100, false ); + sessionPopup->setItemEnabled( 101, false ); + } + sessionPopup->insertSeparator(); + } + SessList sess; + if (dm.localSessions( sess )) + for (SessList::ConstIterator it = sess.begin(); it != sess.end(); ++it) { + int id = sessionPopup->insertItem( DM::sess2Str( *it ), (*it).vt ); + if (!(*it).vt) + sessionPopup->setItemEnabled( id, false ); + if ((*it).self) + sessionPopup->setItemChecked( id, true ); + } + // save + sessionPopup->insertSeparator(); + KConfig ksmserver("ksmserverrc", false, false); + ksmserver.setGroup("General"); + if (ksmserver.readEntry( "loginMode" ) == "restoreSavedSession") + { + sessionPopup->insertItem(fileSaveIcon, i18n("Save Session"), 103); + } + // logout + if (kapp->authorize("logout")) + { + sessionPopup->insertItem(exitIcon, i18n("Log Out..."), 104); + } +} + +void UserManager::slotSessionActivated( int ent ) +{ + switch (ent) + { + case 100: + doNewSession( true ); + break; + case 101: + doNewSession( false ); + break; + case 102: + lock(); + break; + case 103: + saveSession(); + break; + case 104: + logout(); + break; + default: + if (!sessionPopup->isItemChecked( ent )) + DM().lockSwitchVT( ent ); + } +} + +void UserManager::doNewSession( bool lock_ ) +{ + int result = KMessageBox::warningContinueCancel( + kapp->desktop()->screen(kapp->desktop()->screenNumber(this)), + i18n("<p>You have chosen to open another desktop session.<br>" + "The current session will be hidden " + "and a new login screen will be displayed.<br>" + "An F-key is assigned to each session; " + "F%1 is usually assigned to the first session, " + "F%2 to the second session and so on. " + "You can switch between sessions by pressing " + "Ctrl, Alt and the appropriate F-key at the same time. " + "Additionally, the KDE Panel and Desktop menus have " + "actions for switching between sessions.</p>") + .arg(7).arg(8), + i18n("Warning - New Session"), + KGuiItem(i18n("&Start New Session"), "fork"), + ":confirmNewSession", +#if KDE_IS_VERSION(3,4,0) //3.4 + KMessageBox::PlainCaption | +#endif + KMessageBox::Notify); + + if (result==KMessageBox::Cancel) + return; + + if (lock_) + lock(); + + DM().startReserve(); +} + +void UserManager::saveSession() +{ + QByteArray data; + kapp->dcopClient()->send( "ksmserver", "default", + "saveCurrentSession()", data ); +} + + +extern "C" +{ + KPanelApplet* init( QWidget *parent, const QString& configFile) + { + KGlobal::locale()->insertCatalogue("usermanager"); + return new UserManager(configFile, KPanelApplet::Normal, KPanelApplet::About, parent, "usermanager"); + } +} diff --git a/sessionapplet/usermanager.desktop b/sessionapplet/usermanager.desktop new file mode 100644 index 0000000..31c61cf --- /dev/null +++ b/sessionapplet/usermanager.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Encoding=UTF-8 +Comment=Session Control, Lock, Logout, Change +Name=SessionManager +Name[xx]=xxSessionManagerxx +Icon=fork +X-KDE-Library=usermanager_panelapplet +X-KDE-UniqueApplet = true diff --git a/sessionapplet/usermanager.h b/sessionapplet/usermanager.h new file mode 100644 index 0000000..87f8864 --- /dev/null +++ b/sessionapplet/usermanager.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2005 by Thomas Lübking * + * thomas.luebking@web.de * + * * + * 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 USERMANAGER_H +#define USERMANAGER_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <kpanelapplet.h> +#include <qstring.h> +#include <qiconset.h> +#include <qstringlist.h> +#include <kconfig.h> + +class KMenuBar; +class QPopunMenu; +// class QLabel; + +class UserManager : public KPanelApplet +{ + Q_OBJECT + +public: + UserManager(const QString& configFile, Type t = Normal, int actions = 0, + QWidget *parent = 0, const char *name = 0); + /** destructor */ + ~UserManager(); + + virtual void about(); + int heightForWidth(int) const; + int widthForHeight(int) const; + +protected slots: + void slotPopulateSessions(); + void slotSessionActivated( int ); + void slotPopulateLanguages(); + void slotLanguageActivated( int ); + +protected: + void lock(); + void logout(); + void saveSession(); + void doNewSession(bool lock_); + +private: + KConfig *ksConfig; + QWidget *mainView; + KMenuBar *menu; + QPopupMenu *sessionPopup; + QPopupMenu *langPopup; + QStringList langList; + QIconSet exitIcon; + QIconSet lockIcon; + QIconSet fileSaveIcon; +// QLabel *langLabel; +}; + +#endif diff --git a/sessionapplet/usermanager.lsm b/sessionapplet/usermanager.lsm new file mode 100644 index 0000000..cb6f2cd --- /dev/null +++ b/sessionapplet/usermanager.lsm @@ -0,0 +1,16 @@ +Begin3 +Title: UserManager -- Some description +Version: 0.1 +Entered-date: +Description: +Keywords: KDE Qt +Author: Thomas Lübking <thomas.luebking@web.de> +Maintained-by: Thomas Lübking <thomas.luebking@web.de> +Home-page: +Alternate-site: +Primary-site: ftp://ftp.kde.org/pub/kde/unstable/apps/utils + xxxxxx usermanager-0.1.tar.gz + xxx usermanager-0.1.lsm +Platform: Linux. Needs KDE +Copying-policy: GPL +End |