00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "pcmcia.h"
00031 #include "configdialog.h"
00032 #include "promptactiondialog.h"
00033
00034
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
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
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
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
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