author | sandman <sandman> | 2002-10-17 00:39:31 (UTC) |
---|---|---|
committer | sandman <sandman> | 2002-10-17 00:39:31 (UTC) |
commit | 259d10f40405fd77ba0a8947782f716be94da3a5 (patch) (side-by-side diff) | |
tree | 636cb3a899d27a8fe41f377fabc5bd170a74c6dc | |
parent | 5d28c61d84da1814d356540b557bbfe026da98aa (diff) | |
download | opie-259d10f40405fd77ba0a8947782f716be94da3a5.zip opie-259d10f40405fd77ba0a8947782f716be94da3a5.tar.gz opie-259d10f40405fd77ba0a8947782f716be94da3a5.tar.bz2 |
- fix for bug #292 (Improper behaviour of frontlight disabling)
- fix for bug #199 (Desktop visible on resume before password dialog
appears)
-rw-r--r-- | core/launcher/desktop.cpp | 34 | ||||
-rw-r--r-- | library/password.cpp | 24 | ||||
-rw-r--r-- | library/password.h | 1 |
3 files changed, 46 insertions, 13 deletions
diff --git a/core/launcher/desktop.cpp b/core/launcher/desktop.cpp index 0e60839..d74b745 100644 --- a/core/launcher/desktop.cpp +++ b/core/launcher/desktop.cpp @@ -88,349 +88,351 @@ private: }; typedef QValueList<QCopKeyRegister> KeyRegisterList; KeyRegisterList keyRegisterList; static Desktop* qpedesktop = 0; static int loggedin = 0; static void login( bool at_poweron ) { if ( !loggedin ) { Global::terminateBuiltin( "calibrate" ); Password::authenticate( at_poweron ); loggedin = 1; QCopEnvelope e( "QPE/Desktop", "unlocked()" ); } } bool Desktop::screenLocked() { return loggedin == 0; } /* Priority is number of alerts that are needed to pop up alert. */ class DesktopPowerAlerter : public QMessageBox { public: DesktopPowerAlerter( QWidget *parent, const char *name = 0 ) : QMessageBox( tr( "Battery Status" ), "Low Battery", QMessageBox::Critical, QMessageBox::Ok | QMessageBox::Default, QMessageBox::NoButton, QMessageBox::NoButton, parent, name, FALSE ) { currentPriority = INT_MAX; alertCount = 0; } void alert( const QString &text, int priority ); void hideEvent( QHideEvent * ); private: int currentPriority; int alertCount; }; void DesktopPowerAlerter::alert( const QString &text, int priority ) { alertCount++; if ( alertCount < priority ) return ; if ( priority > currentPriority ) return ; currentPriority = priority; setText( text ); show(); } void DesktopPowerAlerter::hideEvent( QHideEvent *e ) { QMessageBox::hideEvent( e ); alertCount = 0; currentPriority = INT_MAX; } class QPEScreenSaver : public QWSScreenSaver { private: int LcdOn; public: QPEScreenSaver() { m_disable_suspend = 100; m_enable_dim = false; m_enable_lightoff = false; m_enable_onlylcdoff = false; m_lcd_status = true; m_backlight_bright = -1; m_backlight_forcedoff = false; // Make sure the LCD is in fact on, (if opie was killed while the LCD is off it would still be off) ODevice::inst ( ) -> setDisplayStatus ( true ); } void restore() { if ( !m_lcd_status ) { // We must have turned it off ODevice::inst ( ) -> setDisplayStatus ( true ); m_lcd_status = true; } - setBacklight ( -3 ); + setBacklight ( -1 ); } bool save( int level ) { switch ( level ) { case 0: if ( m_disable_suspend > 0 && m_enable_dim ) { if ( backlight() > 1 ) setBacklight( 1 ); // lowest non-off } return true; break; case 1: if ( m_disable_suspend > 1 && m_enable_lightoff ) { setBacklight( 0 ); // off } return true; break; case 2: if ( m_enable_onlylcdoff ) { ODevice::inst ( ) -> setDisplayStatus ( false ); m_lcd_status = false; return true; } else // We're going to suspend the whole machine { if ( ( m_disable_suspend > 2 ) && ( PowerStatusManager::readStatus().acStatus() != PowerStatus::Online ) && ( !Network::networkOnline ( ) ) ) { QWSServer::sendKeyEvent( 0xffff, Qt::Key_F34, FALSE, TRUE, FALSE ); return true; } } break; } return false; } private: static int ssi( int interval, Config & config, const QString & enable, const QString & value, int def ) { if ( !enable.isEmpty() && config.readNumEntry( enable, 0 ) == 0 ) return 0; if ( interval < 0 ) { // Restore screen blanking and power saving state interval = config.readNumEntry( value, def ); } return interval; } public: void setIntervals( int i1, int i2, int i3 ) { Config config( "qpe" ); config.setGroup( "Screensaver" ); int v[ 4 ]; i1 = ssi( i1, config, "Dim", "Interval_Dim", 30 ); i2 = ssi( i2, config, "LightOff", "Interval_LightOff", 20 ); i3 = ssi( i3, config, "", "Interval", 60 ); //qDebug("screen saver intervals: %d %d %d", i1, i2, i3); v [ 0 ] = QMAX( 1000 * i1, 100 ); v [ 1 ] = QMAX( 1000 * i2, 100 ); v [ 2 ] = QMAX( 1000 * i3, 100 ); v [ 3 ] = 0; m_enable_dim = ( ( i1 != 0 ) ? config. readNumEntry ( "Dim", 1 ) : false ); m_enable_lightoff = ( ( i2 != 0 ) ? config. readNumEntry ( "LightOff", 1 ) : false ); m_enable_onlylcdoff = config. readNumEntry ( "LcdOffOnly", 0 ); if ( !i1 && !i2 && !i3 ) QWSServer::setScreenSaverInterval( 0 ); else QWSServer::setScreenSaverIntervals( v ); } void setInterval ( int interval ) { setIntervals ( -1, -1, interval ); } void setMode ( int mode ) { if ( mode > m_disable_suspend ) setInterval( -1 ); m_disable_suspend = mode; } int backlight ( ) { if ( m_backlight_bright == -1 ) { // Read from config Config config ( "qpe" ); config. setGroup ( "Screensaver" ); m_backlight_bright = config. readNumEntry ( "Brightness", 255 ); } return m_backlight_bright; } void setBacklight ( int bright ) { if ( bright == -3 ) { // Forced on m_backlight_forcedoff = false; bright = -1; } if ( m_backlight_forcedoff && bright != -2 ) return ; if ( bright == -2 ) { // Toggle between off and on bright = m_backlight_bright ? 0 : -1; m_backlight_forcedoff = !bright; } m_backlight_bright = bright; bright = backlight ( ); ODevice::inst ( ) -> setDisplayBrightness ( bright ); m_backlight_bright = bright; } void setDisplayState ( bool on ) { if ( m_lcd_status != on ) { ODevice::inst ( ) -> setDisplayStatus ( on ); m_lcd_status = on; } } private: int m_disable_suspend; bool m_enable_dim; bool m_enable_lightoff; bool m_enable_onlylcdoff; bool m_lcd_status; int m_backlight_bright; bool m_backlight_forcedoff; }; void DesktopApplication::switchLCD ( bool on ) { if ( qApp ) { DesktopApplication *dapp = (DesktopApplication *) qApp; if ( dapp-> m_screensaver ) { - if ( on ) - dapp-> m_screensaver-> restore ( ); //setBacklight ( on ? -3 : -1 ); - else - dapp-> m_screensaver-> save ( 1 ); - - } + if ( on ) { + dapp-> m_screensaver-> setDisplayState ( true ); + dapp-> m_screensaver-> setBacklight ( -3 ); + } + else { + dapp-> m_screensaver-> setDisplayState ( false ); + } + } } } DesktopApplication::DesktopApplication( int& argc, char **argv, Type appType ) : QPEApplication( argc, argv, appType ) { QTimer * t = new QTimer( this ); connect( t, SIGNAL( timeout() ), this, SLOT( psTimeout() ) ); t->start( 10000 ); ps = new PowerStatus; pa = new DesktopPowerAlerter( 0 ); channel = new QCopChannel( "QPE/Desktop", this ); connect( channel, SIGNAL( received( const QCString&, const QByteArray& ) ), this, SLOT( desktopMessage( const QCString&, const QByteArray& ) ) ); channel = new QCopChannel( "QPE/System", this ); connect( channel, SIGNAL( received( const QCString&, const QByteArray& ) ), this, SLOT( systemMessage( const QCString&, const QByteArray& ) ) ); m_screensaver = new QPEScreenSaver; m_screensaver-> setInterval ( -1 ); QWSServer::setScreenSaver( m_screensaver ); } DesktopApplication::~DesktopApplication() { delete ps; delete pa; } void DesktopApplication::desktopMessage( const QCString &msg, const QByteArray &data ) { #ifdef Q_WS_QWS QDataStream stream( data, IO_ReadOnly ); if ( msg == "keyRegister(int key, QString channel, QString message)" ) { int k; QString c, m; stream >> k; stream >> c; stream >> m; qWarning( "KeyRegisterReceived: %i, %s, %s", k, ( const char* ) c, ( const char * ) m ); keyRegisterList.append( QCopKeyRegister( k, c, m ) ); } #endif } void DesktopApplication::systemMessage( const QCString & msg, const QByteArray & data ) { #ifdef Q_WS_QWS QDataStream stream ( data, IO_ReadOnly ); if ( msg == "setScreenSaverInterval(int)" ) { int time; stream >> time; m_screensaver-> setInterval( time ); } else if ( msg == "setScreenSaverIntervals(int,int,int)" ) { int t1, t2, t3; stream >> t1 >> t2 >> t3; m_screensaver-> setIntervals( t1, t2, t3 ); } else if ( msg == "setBacklight(int)" ) { int bright; stream >> bright; m_screensaver-> setBacklight( bright ); } else if ( msg == "setScreenSaverMode(int)" ) { int mode; stream >> mode; m_screensaver-> setMode ( mode ); } else if ( msg == "setDisplayState(int)" ) { int state; stream >> state; m_screensaver-> setDisplayState ( state != 0 ); } else if ( msg == "suspend()" ) { emit power(); } #endif } enum MemState { Unknown, VeryLow, Low, Normal } memstate = Unknown; #ifdef Q_WS_QWS bool DesktopApplication::qwsEventFilter( QWSEvent *e ) { qpedesktop->checkMemory(); @@ -769,211 +771,221 @@ void Desktop::executeOrModify( const QString& appLnkFile ) } } void Desktop::raiseDatebook() { Config cfg( "qpe" ); //F9 'Activity' cfg.setGroup( "AppsKey" ); QString tempItem; tempItem = cfg.readEntry( "LeftEnd" , "Calendar" ); if ( tempItem == "Calendar" || tempItem.isEmpty() ) { tempItem = "datebook"; } QCopEnvelope e( "QPE/System", "execute(QString)" ); e << tempItem; } void Desktop::raiseContacts() { Config cfg( "qpe" ); //F10, 'Contacts' cfg.setGroup( "AppsKey" ); QString tempItem; tempItem = cfg.readEntry( "Left2nd", "Address Book" ); if ( tempItem == "Address Book" || tempItem.isEmpty() ) { tempItem = "addressbook"; } QCopEnvelope e( "QPE/System", "execute(QString)" ); e << tempItem; } void Desktop::raiseMenu() { Config cfg( "qpe" ); //F11, 'Menu cfg.setGroup( "AppsKey" ); QString tempItem; tempItem = cfg.readEntry( "Right2nd" , "Popup Menu" ); if ( tempItem == "Popup Menu" || tempItem.isEmpty() ) { Global::terminateBuiltin( "calibrate" ); tb->startMenu() ->launch(); } else { QCopEnvelope e( "QPE/System", "execute(QString)" ); e << tempItem; } } void Desktop::raiseEmail() { Config cfg( "qpe" ); //F13, 'Mail' // only in zaurus, on ipaq mail key is F11 cfg.setGroup( "AppsKey" ); QString tempItem; tempItem = cfg.readEntry( "RightEnd", "Mail" ); if ( tempItem == "Mail" || tempItem == "qtmail" || tempItem.isEmpty() ) { tempItem = "mail"; } QCopEnvelope e( "QPE/System", "execute(QString)" ); e << tempItem; } // autoStarts apps on resume and start void Desktop::execAutoStart() { QString appName; int delay; QDateTime now = QDateTime::currentDateTime(); Config cfg( "autostart" ); cfg.setGroup( "AutoStart" ); appName = cfg.readEntry( "Apps", "" ); delay = ( cfg.readEntry( "Delay", "0" ) ).toInt(); // If the time between suspend and resume was longer then the // value saved as delay, start the app if ( suspendTime.secsTo( now ) >= ( delay * 60 ) && !appName.isEmpty() ) { QCopEnvelope e( "QPE/System", "execute(QString)" ); e << QString( appName ); } } #if defined(QPE_HAVE_TOGGLELIGHT) #include <qpe/config.h> #include <sys/ioctl.h> #include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <linux/ioctl.h> #include <time.h> #endif void Desktop::togglePower() { static bool excllock = false; qDebug ( "togglePower (locked == %d)", excllock ? 1 : 0 ); if ( excllock ) - return ; + return; excllock = true; bool wasloggedin = loggedin; loggedin = 0; suspendTime = QDateTime::currentDateTime(); - ODevice::inst ( ) -> suspend ( ); +#ifdef QWS + if ( Password::needToAuthenticate ( true ) && qt_screen ) { + // Should use a big black window instead. + // But this would not show up fast enough + QGfx *g = qt_screen-> screenGfx ( ); + g-> fillRect ( 0, 0, qt_screen-> width ( ), qt_screen-> height ( )); + delete g; + } +#endif + + ODevice::inst ( )-> suspend ( ); - QWSServer::screenSaverActivate ( false ); DesktopApplication::switchLCD ( true ); // force LCD on without slow qcop call + QWSServer::screenSaverActivate ( false ); { QCopEnvelope( "QPE/Card", "mtabChanged()" ); // might have changed while asleep } if ( wasloggedin ) - login( TRUE ); + login ( true ); execAutoStart(); //qcopBridge->closeOpenConnections(); excllock = false; } void Desktop::toggleLight() { QCopEnvelope e( "QPE/System", "setBacklight(int)" ); e << -2; // toggle } void Desktop::toggleSymbolInput() { tb->toggleSymbolInput(); } void Desktop::toggleNumLockState() { tb->toggleNumLockState(); } void Desktop::toggleCapsLockState() { tb->toggleCapsLockState(); } void Desktop::styleChange( QStyle &s ) { QWidget::styleChange( s ); int displayw = qApp->desktop() ->width(); int displayh = qApp->desktop() ->height(); QSize sz = tb->sizeHint(); tb->setGeometry( 0, displayh - sz.height(), displayw, sz.height() ); } void DesktopApplication::shutdown() { if ( type() != GuiServer ) return ; ShutdownImpl *sd = new ShutdownImpl( 0, 0, WDestructiveClose ); connect( sd, SIGNAL( shutdown( ShutdownImpl::Type ) ), this, SLOT( shutdown( ShutdownImpl::Type ) ) ); sd->showMaximized(); } void DesktopApplication::shutdown( ShutdownImpl::Type t ) { switch ( t ) { case ShutdownImpl::ShutdownSystem: execlp( "shutdown", "shutdown", "-h", "now", ( void* ) 0 ); break; case ShutdownImpl::RebootSystem: execlp( "shutdown", "shutdown", "-r", "now", ( void* ) 0 ); break; case ShutdownImpl::RestartDesktop: restart(); break; case ShutdownImpl::TerminateDesktop: prepareForTermination( FALSE ); // This is a workaround for a Qt bug // clipboard applet has to stop its poll timer, or Qt/E // will hang on quit() right before it emits aboutToQuit() emit aboutToQuit ( ); quit(); break; } } void DesktopApplication::restart() { prepareForTermination( TRUE ); #ifdef Q_WS_QWS for ( int fd = 3; fd < 100; fd++ ) close( fd ); #if defined(QT_DEMO_SINGLE_FLOPPY) execl( "/sbin/init", "qpe", 0 ); #elif defined(QT_QWS_CASSIOPEIA) execl( "/bin/sh", "sh", 0 ); #else execl( ( qpeDir() + "/bin/qpe" ).latin1(), "qpe", 0 ); #endif exit( 1 ); #endif } diff --git a/library/password.cpp b/library/password.cpp index 4b22b65..6d126c4 100644 --- a/library/password.cpp +++ b/library/password.cpp @@ -1,126 +1,126 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "password.h" #include "config.h" #include "global.h" #include "backend/contact.h" #include <qlabel.h> #include <qlineedit.h> #include <qtextview.h> #include <qstring.h> #include <qapplication.h> #include <qfile.h> -#include <qwindowsystem_qws.h> +//#include <qwindowsystem_qws.h> #include <qdialog.h> #include <unistd.h> //for sleep #include "passwordbase_p.h" class PasswordDialog : public PasswordBase { Q_OBJECT public: PasswordDialog( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); ~PasswordDialog(); void clear(); void setPrompt( const QString& ); signals: void passwordEntered( const QString& ); protected: bool eventFilter( QObject*, QEvent* ); void keyPressEvent( QKeyEvent * ); private: void input( QString ); friend class Password; QString text; }; extern "C" char *crypt(const char *key, const char *salt); static QString qcrypt(const QString& k, const char *salt) { return QString::fromUtf8(crypt(k.utf8(),salt)); } /* * Constructs a PasswordDialog which is a child of 'parent', with the * name 'name' and widget flags set to 'f' */ PasswordDialog::PasswordDialog( QWidget* parent, const char* name, WFlags fl ) : PasswordBase( parent, name, fl ) { QRect desk = qApp->desktop()->geometry(); if ( desk.width() < 220 ) { QFont f( font() ); f.setPointSize( 18 ); setFont( f ); f.setPointSize( 12 ); prompt->setFont( f ); } button_0->installEventFilter( this ); button_1->installEventFilter( this ); button_2->installEventFilter( this ); button_3->installEventFilter( this ); button_4->installEventFilter( this ); button_5->installEventFilter( this ); button_6->installEventFilter( this ); button_7->installEventFilter( this ); button_8->installEventFilter( this ); button_9->installEventFilter( this ); button_OK->installEventFilter( this ); setFocus(); } /* * Destroys the object and frees any allocated resources */ PasswordDialog::~PasswordDialog() { // no need to delete child widgets, Qt does it all for us } /*! \reimp */ bool PasswordDialog::eventFilter( QObject*o, QEvent*e ) { if ( e->type() == QEvent::MouseButtonRelease ) { if ( o == button_OK ) { emit passwordEntered( text ); } else { QLabel *l = (QLabel*)o; input(l->text()); } } return FALSE; } @@ -192,142 +192,162 @@ public: passw->clear(); } void execNonModal() { if ( !modl ) { reset(); showFullScreen(); do { qApp->enter_loop(); } while (result()!=1); } } void accept() { if ( !modl ) qApp->exit_loop(); QDialog::accept(); } PasswordDialog *passw; bool modl; }; class OwnerDlg : public QDialog { public: OwnerDlg( QWidget *parent, const char * name, Contact c, bool modal, bool fullscreen = FALSE ) : QDialog( parent, name, modal, fullscreen ? WStyle_NoBorder | WStyle_Customize | WStyle_StaysOnTop : 0 ) { if ( fullscreen ) { QRect desk = qApp->desktop()->geometry(); setGeometry( 0, 0, desk.width(), desk.height() ); } // set up contents. QString text = "<H1>" + tr("Owner Information") + "</H1>"; text += c.toRichText(); tv = new QTextView(this); tv->setText(text); tv->viewport()->installEventFilter(this); } void resizeEvent( QResizeEvent * ) { tv->resize( size() ); } bool eventFilter(QObject *o, QEvent *e) { if (e->type() == QEvent::KeyPress || e->type() == QEvent::MouseButtonPress ) { accept(); return TRUE; } return QWidget::eventFilter(o, e); } void mousePressEvent( QMouseEvent * ) { accept(); } private: QTextView *tv; }; /*! Returns a crypted password entered by the user when prompted with \a prompt The returned value is QString::null if the user cancels the operation, or the empty string if the user enters no password (but confirms the dialog). */ QString Password::getPassword( const QString& prompt ) { PasswdDlg pd(0,0,TRUE); pd.passw->setPrompt( prompt ); pd.showMaximized(); int r = pd.exec(); if ( r == QDialog::Accepted ) { if (pd.passw->text.isEmpty()) return ""; else return qcrypt(pd.passw->text,"a0"); } else { return QString::null; } } /*! + Return if a prompt for the user's passcode is needed. + + If \a at_poweron is TRUE, the dialog is only used if the user's + preference request it at poweron + + Opie extension to speed up suspend/resume. +*/ + +bool Password::needToAuthenticate(bool at_poweron) +{ + Config cfg("Security"); + cfg.setGroup("Passcode"); + QString passcode = cfg.readEntry("passcode"); + + return ( !passcode.isEmpty() + && (!at_poweron || cfg.readNumEntry("passcode_poweron",0)) ); +} + +/*! Prompt, fullscreen, for the user's passcode until they get it right. If \a at_poweron is TRUE, the dialog is only used if the user's preference request it at poweron; either way, the screen is always repainted by this function. (this functionality may move to the caller of this function). */ void Password::authenticate(bool at_poweron) { Config cfg("Security"); cfg.setGroup("Passcode"); QString passcode = cfg.readEntry("passcode"); if ( !passcode.isEmpty() && (!at_poweron || cfg.readNumEntry("passcode_poweron",0)) ) { // Do it as a fullscreen modal dialog PasswdDlg pd(0,0,TRUE,TRUE); // see if there is contact information. OwnerDlg *oi = 0; QString vfilename = Global::applicationFileName("addressbook", "businesscard.vcf"); if (QFile::exists(vfilename)) { Contact c; c = Contact::readVCard( vfilename )[0]; oi = new OwnerDlg(0, 0, c, TRUE, TRUE); } pd.reset(); pd.exec(); while (qcrypt(pd.passw->text, "a0") != passcode) { if (oi) oi->exec(); pd.reset(); pd.exec(); } } else if ( at_poweron ) { // refresh screen #### should probably be in caller - // Not needed (we took away the screen blacking) + // Not needed (we took away the screen blacking) TT + // Not needed (we have intelligent screen blacking) sandman //if ( qwsServer ) //qwsServer->refresh(); } } #include "password.moc" diff --git a/library/password.h b/library/password.h index a3a3e45..a2f2c3c 100644 --- a/library/password.h +++ b/library/password.h @@ -1,32 +1,33 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #ifndef PASSWORD_H #define PASSWORD_H #include <qstring.h> class Password { public: + static bool needToAuthenticate(bool atpoweron=FALSE); // Opie extension to speed up suspend/resume (sandman) static void authenticate(bool atpoweron=FALSE); static QString getPassword( const QString& prompt ); }; #endif // PASSWORD_H |