Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

pcmcia.cpp

Go to the documentation of this file.
00001 /*
00002                              This file is part of the Opie Project
00003              =.              (C) 2005 Michael 'Mickey' Lauer <mickey@Vanille.de>
00004             .=l.
00005            .>+-=
00006  _;:,     .>    :=|.         This program is free software; you can
00007 .> <`_,   >  .   <=          redistribute it and/or  modify it under
00008 :`=1 )Y*s>-.--   :           the terms of the GNU Library General Public
00009 .="- .-=="i,     .._         License as published by the Free Software
00010  - .   .-<_>     .<>         Foundation; either version 2 of the License,
00011      ._= =}       :          or (at your option) any later version.
00012     .%`+i>       _;_.
00013     .i_,=:_.      -<s.       This program is distributed in the hope that
00014      +  .  -:.       =       it will be useful,  but WITHOUT ANY WARRANTY;
00015     : ..    .:,     . . .    without even the implied warranty of
00016     =_        +     =;=|`    MERCHANTABILITY or FITNESS FOR A
00017   _.=:.       :    :=>`:     PARTICULAR PURPOSE. See the GNU
00018 ..}^=.=       =       ;      Library General Public License for more
00019 ++=   -.     .`     .:       details.
00020  :     =  ...= . :.=-
00021  -.   .:....=;==+<;          You should have received a copy of the GNU
00022   -_. . .   )=.  =           Library General Public License along with
00023     --        :-=`           this library; see the file COPYING.LIB.
00024                              If not, write to the Free Software Foundation,
00025                              Inc., 59 Temple Place - Suite 330,
00026                              Boston, MA 02111-1307, USA.
00027 
00028 */
00029 
00030 #include "pcmcia.h"
00031 #include "configdialog.h"
00032 #include "promptactiondialog.h"
00033 
00034 /* OPIE */
00035 #include <opie2/odebug.h>
00036 #include <opie2/odevice.h>
00037 #include <opie2/oconfig.h>
00038 #include <opie2/oprocess.h>
00039 #include <opie2/opcmciasystem.h>
00040 #include <opie2/oresource.h>
00041 #include <opie2/otaskbarapplet.h>
00042 #include <qpe/applnk.h>
00043 #include <qpe/global.h>
00044 #include <qpe/resource.h>
00045 using namespace Opie::Core;
00046 using namespace Opie::Ui;
00047 
00048 /* QT */
00049 #include <qcombobox.h>
00050 #include <qcopchannel_qws.h>
00051 #include <qpainter.h>
00052 #include <qfile.h>
00053 #include <qtextstream.h>
00054 #include <qmessagebox.h>
00055 #include <qsound.h>
00056 #include <qtimer.h>
00057 
00058 /* STD */
00059 #include <stdio.h>
00060 #include <unistd.h>
00061 #include <stdlib.h>
00062 #include <string.h>
00063 #include <errno.h>
00064 #include <fcntl.h>
00065 #if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
00066 #include <sys/vfs.h>
00067 #include <mntent.h>
00068 #endif
00069 
00070 PcmciaManager::PcmciaManager( QWidget * parent ) : QWidget( parent ), popupMenu( 0 )
00071 {
00072     QCopChannel * pcmciaChannel = new QCopChannel( "QPE/Card", this );
00073     connect( pcmciaChannel,
00074              SIGNAL( received(const QCString&,const QByteArray&) ), this,
00075              SLOT( cardMessage(const QCString&,const QByteArray&) ) );
00076 
00077     setFocusPolicy( NoFocus );
00078     setFixedWidth ( AppLnk::smallIconSize() );
00079     setFixedHeight ( AppLnk::smallIconSize() );
00080     pm = Opie::Core::OResource::loadPixmap( "pcmcia", Opie::Core::OResource::SmallIcon );
00081     configuring = false;
00082 
00083     QCopChannel *channel = new QCopChannel( "QPE/System", this );
00084     connect( channel, SIGNAL(received(const QCString&,const QByteArray&)),
00085                 this, SLOT(handleSystemChannel(const QCString&,const QByteArray&)) );
00086 }
00087 
00088 
00089 PcmciaManager::~PcmciaManager()
00090 {
00091 }
00092 
00093 void PcmciaManager::handleSystemChannel( const QCString&msg, const QByteArray& )
00094 {
00095     if ( msg == "returnFromSuspend()" )
00096     {
00097         if ( !OPcmciaSystem::instance()->cardCount() ) return;
00098         OPcmciaSystem* sys = OPcmciaSystem::instance();
00099         OPcmciaSystem::CardIterator it = sys->iterator();
00100 
00101         while ( it.current() )
00102         {
00103             if ( !it.current()->isEmpty() )
00104             {
00105                 executeAction( it.current(), "resume" );
00106             }
00107         ++it;
00108         }
00109     }
00110 }
00111 
00112 void PcmciaManager::popUp( QString message, QString icon )
00113 {
00114     if ( !popupMenu)
00115     {
00116         popupMenu = new QPopupMenu( this );
00117         popupMenu->setFocusPolicy( QWidget::NoFocus );
00118     }
00119     popupMenu->clear();
00120 
00121     if ( icon.isEmpty() ) {
00122         popupMenu->insertItem( message, 0 );
00123     } else {
00124         popupMenu->insertItem( QIconSet( Opie::Core::OResource::loadPixmap( icon, Opie::Core::OResource::SmallIcon ) ),
00125                                message, 0 );
00126     }
00127 
00128     QPoint p = mapToGlobal( QPoint( 0, 0 ) );
00129     QSize s = popupMenu->sizeHint();
00130     popupMenu->popup( QPoint( p.x() + ( width() / 2 ) - ( s.width() / 2 ),
00131                               p.y() - s.height() ), 0 );
00132 
00133     QTimer::singleShot( 2000, this, SLOT( popupTimeout() ) );
00134 }
00135 
00136 
00137 void PcmciaManager::popupTimeout()
00138 {
00139     popupMenu->hide();
00140 }
00141 
00142 enum { EJECT, INSERT, SUSPEND, RESUME, RESET, CONFIGURE, ACTIVATE };
00143 static const char* actionText[] = { "eject", "insert", "suspend", "resum", "resett", "configur", "activat" };
00144 
00145 void PcmciaManager::mousePressEvent( QMouseEvent* )
00146 {
00147     QPopupMenu* menu = new QPopupMenu( this );
00148     QStringList cmd;
00149     bool execute = true;
00150 
00151     OPcmciaSystem* sys = OPcmciaSystem::instance();
00152     sys->synchronize();
00153     OPcmciaSystem::CardIterator it = sys->iterator();
00154     if ( !sys->count() ) return;
00155 
00156     int i = 0;
00157     while ( it.current() )
00158     {
00159         QPopupMenu* submenu = new QPopupMenu( menu );
00160         submenu->insertItem( "&Eject",     EJECT+i*100 );
00161         submenu->insertItem( "&Insert",    INSERT+i*100 );
00162         submenu->insertItem( "&Suspend",   SUSPEND+i*100 );
00163         submenu->insertItem( "&Resume",    RESUME+i*100 );
00164         submenu->insertItem( "Rese&t",     RESET+i*100 );
00165         submenu->insertItem( "&Configure", CONFIGURE+i*100 );
00166 
00167         bool isSuspended = it.current()->isSuspended();
00168         bool isEmpty = it.current()->isEmpty();
00169 
00170         submenu->setItemEnabled( EJECT+i*100, !isEmpty );
00171         submenu->setItemEnabled( INSERT+i*100, isEmpty );
00172         submenu->setItemEnabled( SUSPEND+i*100, !isEmpty && !isSuspended );
00173         submenu->setItemEnabled( RESUME+i*100, !isEmpty && isSuspended );
00174         submenu->setItemEnabled( RESET+i*100, !isEmpty && !isSuspended );
00175         submenu->setItemEnabled( CONFIGURE+i*100, !isEmpty && !configuring );
00176 
00177         connect( submenu, SIGNAL(activated(int)), this, SLOT(userCardAction(int)) );
00178         menu->insertItem( tr( "%1: %2" ).arg( i++ ).arg( it.current()->identity() ), submenu, 1 );
00179         ++it;
00180     }
00181 
00182     QPoint p = mapToGlobal( QPoint( 0, 0 ) );
00183     QSize s = menu->sizeHint();
00184     int opt = menu->exec( QPoint( p.x() + ( width() / 2 ) - ( s.width() / 2 ), p.y() - s.height() ), 0 );
00185     qDebug( "pcmcia: menu result = %d", opt );
00186     delete menu;
00187 }
00188 
00189 
00190 void PcmciaManager::cardMessage( const QCString & msg, const QByteArray & )
00191 {
00192     odebug << "PcmciaManager::cardMessage( '" << msg << "' )" << oendl;
00193     if ( msg != "stabChanged()" ) return;
00194 
00195     /* check if a previously unknown card has been inserted */
00196     OPcmciaSystem::instance()->synchronize();
00197 
00198     if ( !OPcmciaSystem::instance()->cardCount() ) return;
00199 
00200     OConfig cfg( "PCMCIA" );
00201     cfg.setGroup( "Global" );
00202     int nCards = cfg.readNumEntry( "nCards", 0 );
00203 
00204     OPcmciaSystem* sys = OPcmciaSystem::instance();
00205     OPcmciaSystem::CardIterator it = sys->iterator();
00206 
00207     bool newCard = true;
00208     OPcmciaSocket* theCard = 0;
00209 
00210     while ( it.current() && newCard )
00211     {
00212         if ( it.current()->isEmpty() )
00213         {
00214             odebug << "pcmcia: skipping empty card in socket " << it.current()->number() << oendl;
00215             ++it;
00216             continue;
00217         }
00218         else
00219         {
00220             theCard = it.current();
00221             QString cardName = theCard->productIdentity();
00222             for ( int i = 0; i < nCards; ++i )
00223             {
00224                 QString cardSection = QString( "Card_%1" ).arg( i );
00225                 cfg.setGroup( cardSection );
00226                 QString name = cfg.readEntry( "name" );
00227                 odebug << "pcmcia: comparing card '" << cardName << "' with known card '" << name << "'" << oendl;
00228                 if ( cardName == name )
00229                 {
00230                     newCard = false;
00231                     odebug << "pcmcia: we have seen this card before" << oendl;
00232                     executeAction( theCard, "insert" );
00233                     break;
00234                 }
00235             }
00236             if ( !newCard ) ++it; else break;
00237         }
00238     }
00239     if ( newCard )
00240     {
00241         odebug << "pcmcia: unconfigured card detected" << oendl;
00242         QString newCardName = theCard->productIdentity();
00243         int result = QMessageBox::information( qApp->desktop(),
00244                                            tr( "PCMCIA/CF Subsystem" ),
00245                                            tr( "<qt>You have inserted the card<br/><b>%1</b><br/>This card is not yet configured. Do you want to configure it now?</qt>" ).arg( newCardName ),
00246                                            tr( "Yes" ), tr( "No" ), 0, 0, 1 );
00247         odebug << "pcmcia: result = " << result << oendl;
00248         if ( result == 0 )
00249         {
00250             configure( theCard );
00251         }
00252         else
00253         {
00254             odebug << "pcmcia: user doesn't want to configure " << newCardName << " now." << oendl;
00255         }
00256     }
00257     else // it's an already configured card
00258     {
00259         odebug << "pcmcia: doing nothing... why do we come here?" << oendl;
00260     }
00261 }
00262 
00263 void PcmciaManager::paintEvent( QPaintEvent * )
00264 {
00265     QPainter p( this );
00266     p.drawPixmap( 0, 0, pm );
00267 }
00268 
00269 int PcmciaManager::position()
00270 {
00271     return 7;
00272 }
00273 
00274 void PcmciaManager::execCommand( const QStringList &strList )
00275 {
00276 }
00277 
00278 void PcmciaManager::userCardAction( int action )
00279 {
00280     odebug << "pcmcia: user action on socket " << action / 100 << " requested. action = " << action << oendl;
00281 
00282     int socket = action / 100;
00283     int what = action % 100;
00284     bool success = false;
00285 
00286     switch ( what )
00287     {
00288         case CONFIGURE:
00289         {
00290             QString insertAction; QString resumeAction; QString driver; QString conf;
00291             configure( OPcmciaSystem::instance()->socket( socket ) );
00292             return;
00293         }
00294         case EJECT:    success = OPcmciaSystem::instance()->socket( socket )->eject();
00295                        break;
00296         case INSERT:   success = OPcmciaSystem::instance()->socket( socket )->insert();
00297                        break;
00298         case SUSPEND:  success = OPcmciaSystem::instance()->socket( socket )->suspend();
00299                        break;
00300         case RESUME:   success = OPcmciaSystem::instance()->socket( socket )->resume();
00301                        break;
00302         case RESET:    success = OPcmciaSystem::instance()->socket( socket )->reset();
00303                        break;
00304         case ACTIVATE: success = true;
00305                        break;
00306         default:       odebug << "pcmcia: not yet implemented" << oendl;
00307     }
00308 
00309     if ( success )
00310     {
00311         odebug << tr( "Successfully %1ed card in socket #%2" ).arg( actionText[action] ).arg( socket ) << oendl;
00312         popUp( tr( "Successfully %1ed card in socket #%2" ).arg( actionText[action] ).arg( socket ) );
00313     }
00314     else
00315     {
00316         odebug << tr( "Error while %1ing card in socket #%2" ).arg( actionText[action] ).arg( socket ) << oendl;
00317         popUp( tr( "Error while %1ing card in socket #%2" ).arg( actionText[action] ).arg( socket ) );
00318     }
00319 }
00320 
00321 void PcmciaManager::configure( OPcmciaSocket* card )
00322 {
00323     configuring = true;
00324     ConfigDialog dialog( card, qApp->desktop() );
00325     int result = QPEApplication::execDialog( &dialog, false );
00326     configuring = false;
00327     odebug << "pcmcia: configresult = " << result << oendl;
00328     if ( result )
00329     {
00330         dialog.writeConfiguration( card );
00331     }
00332 }
00333 
00334 void PcmciaManager::executeAction( Opie::Core::OPcmciaSocket* card, const QString& type )
00335 {
00336     odebug << "pcmcia: performing " << type << " action ..." << oendl;
00337     QString theAction = ConfigDialog::preferredAction( card, type );
00338     int intAction = card->number() * 100;
00339 
00340     if ( theAction == "prompt for" )
00341     {
00342         PromptActionDialog dialog( qApp->desktop(), "promptfor", true );
00343         dialog.setCaption( QString( "Choose action for card #%1" ).arg( card->number() ) );
00344         int result = QPEApplication::execDialog( &dialog, true );
00345         odebug << "pcmcia: configresult = " << result << oendl;
00346         if ( result )
00347         {
00348             theAction = dialog.cbAction->currentText();
00349         }
00350         else
00351         {
00352             odebug << "pcmcia: prompted to do nothing" << oendl;
00353             return;
00354         }
00355     }
00356     if ( theAction == "activate" ) intAction += ACTIVATE;
00357     else if ( theAction == "eject" ) intAction += EJECT;
00358     else if ( theAction == "suspend" ) intAction += SUSPEND;
00359     else
00360     {
00361         owarn << "pcmcia: action '" << theAction << "' not known. Huh?" << oendl;
00362         return;
00363     }
00364     userCardAction( intAction );
00365 }
00366 
00367 EXPORT_OPIE_APPLET_v1( PcmciaManager )
00368 

Generated on Sat Nov 5 16:16:45 2005 for OPIE by  doxygen 1.4.2