00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "cardmon.h"
00020
00021
00022 #include <opie2/odebug.h>
00023 #include <opie2/odevice.h>
00024 #include <opie2/oprocess.h>
00025 #include <opie2/oresource.h>
00026 #include <opie2/otaskbarapplet.h>
00027
00028 #include <qpe/applnk.h>
00029 #include <qpe/resource.h>
00030 using namespace Opie::Core;
00031 using namespace Opie::Ui;
00032
00033
00034 #include <qcopchannel_qws.h>
00035 #include <qpainter.h>
00036 #include <qfile.h>
00037 #include <qtextstream.h>
00038 #include <qsound.h>
00039 #include <qtimer.h>
00040
00041
00042 #include <stdio.h>
00043 #include <unistd.h>
00044 #include <stdlib.h>
00045 #include <string.h>
00046 #include <fcntl.h>
00047 #if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
00048 #include <sys/vfs.h>
00049 #include <mntent.h>
00050 #endif
00051
00052 CardMonitor::CardMonitor( QWidget * parent ) : QWidget( parent )
00053 {
00054 pm = Opie::Core::OResource::loadPixmap( "pcmcia", Opie::Core::OResource::SmallIcon );
00055
00056 QCopChannel * pcmciaChannel = new QCopChannel( "QPE/Card", this );
00057 connect( pcmciaChannel,
00058 SIGNAL( received(const QCString&,const QByteArray&) ), this,
00059 SLOT( cardMessage(const QCString&,const QByteArray&) ) );
00060
00061 QCopChannel *sdChannel = new QCopChannel( "QPE/Card", this );
00062 connect( sdChannel,
00063 SIGNAL( received(const QCString&,const QByteArray&) ), this,
00064 SLOT( cardMessage(const QCString&,const QByteArray&) ) );
00065
00066 cardInPcmcia0 = FALSE;
00067 cardInPcmcia1 = FALSE;
00068 cardInSd = FALSE;
00069 m_process = 0;
00070
00071 setFocusPolicy( NoFocus );
00072
00073 setFixedWidth ( AppLnk::smallIconSize() );
00074 setFixedHeight ( AppLnk::smallIconSize() );
00075
00076 getStatusPcmcia( TRUE );
00077 getStatusSd( TRUE );
00078 repaint( FALSE );
00079 popupMenu = 0;
00080 }
00081
00082 CardMonitor::~CardMonitor() {
00083 delete popupMenu;
00084 }
00085
00086 void CardMonitor::popUp( QString message, QString icon ) {
00087 if ( !popupMenu ) {
00088 popupMenu = new QPopupMenu( this );
00089 }
00090
00091 popupMenu->clear();
00092 if ( icon.isEmpty() ) {
00093 popupMenu->insertItem( message, 0 );
00094 } else {
00095 popupMenu->insertItem( QIconSet( Opie::Core::OResource::loadPixmap( icon, Opie::Core::OResource::SmallIcon ) ),
00096 message, 0 );
00097 }
00098
00099 QPoint p = mapToGlobal( QPoint( 0, 0 ) );
00100 QSize s = popupMenu->sizeHint();
00101 popupMenu->popup( QPoint( p.x() + ( width() / 2 ) - ( s.width() / 2 ),
00102 p.y() - s.height() ), 0 );
00103
00104 QTimer::singleShot( 2000, this, SLOT( popupTimeout() ) );
00105 }
00106
00107 void CardMonitor::popupTimeout() {
00108 popupMenu->hide();
00109 }
00110
00111 void CardMonitor::mousePressEvent( QMouseEvent * ) {
00112 QPopupMenu * menu = new QPopupMenu( this );
00113 QStringList cmd;
00114 bool execute = true;
00115
00116 if ( cardInSd ) {
00117 menu->insertItem( QIconSet( Opie::Core::OResource::loadPixmap( "cardmon/ide", Opie::Core::OResource::SmallIcon ) ),
00118 tr( "Eject SD/MMC card" ), 0 );
00119 }
00120
00121 if ( cardInPcmcia0 ) {
00122 menu->
00123 insertItem( QIconSet
00124 ( Opie::Core::OResource::loadPixmap( "cardmon/" + cardInPcmcia0Type, Opie::Core::OResource::SmallIcon ) ),
00125 tr( "Eject card 0: %1" ).arg( cardInPcmcia0Name ), 1 );
00126 }
00127
00128 if ( cardInPcmcia1 ) {
00129 menu->
00130 insertItem( QIconSet
00131 ( Opie::Core::OResource::loadPixmap( "cardmon/" + cardInPcmcia1Type, Opie::Core::OResource::SmallIcon ) ),
00132 tr( "Eject card 1: %1" ).arg( cardInPcmcia1Name ), 2 );
00133 }
00134
00135 QPoint p = mapToGlobal( QPoint( 0, 0 ) );
00136 QSize s = menu->sizeHint();
00137 int opt = menu->exec( QPoint( p.x() + ( width() / 2 ) - ( s.width() / 2 ),
00138 p.y() - s.height() ), 0 );
00139
00140 if ( opt == 1 ) {
00141 m_commandOrig = PCMCIA_Socket1;
00142 cmd << "/sbin/cardctl" << "eject" << "0";
00143 } else if ( opt == 0 ) {
00144 m_commandOrig = MMC_Socket;
00145 cmd << "umount" << cardSdName;
00146 } else if ( opt == 2 ) {
00147 m_commandOrig = PCMCIA_Socket2;
00148 cmd << "/sbin/cardctl" << "eject" << "1";
00149 }else
00150 execute = false;
00151
00152 if ( execute )
00153 execCommand( cmd );
00154
00155 delete menu;
00156 }
00157
00158
00159 void CardMonitor::cardMessage( const QCString & msg, const QByteArray & ) {
00160 if ( msg == "stabChanged()" ) {
00161
00162 getStatusPcmcia();
00163 } else if ( msg == "mtabChanged()" ) {
00164
00165 getStatusSd();
00166 }
00167 }
00168
00169 bool CardMonitor::getStatusPcmcia( int showPopUp ) {
00170
00171 bool cardWas0 = cardInPcmcia0;
00172 bool cardWas1 = cardInPcmcia1;
00173
00174 QString fileName;
00175
00176
00177 if ( QFile::exists( "/var/run/stab" ) ) {
00178 fileName = "/var/run/stab";
00179 } else if ( QFile::exists( "/var/state/pcmcia/stab" ) ) {
00180 fileName = "/var/state/pcmcia/stab";
00181 } else {
00182 fileName = "/var/lib/pcmcia/stab";
00183 }
00184
00185 QFile f( fileName );
00186
00187 if ( f.open( IO_ReadOnly ) ) {
00188 QStringList list;
00189 QTextStream stream( &f );
00190 QString streamIn;
00191 streamIn = stream.read();
00192 list = QStringList::split( "\n", streamIn );
00193 for ( QStringList::Iterator line = list.begin(); line != list.end();
00194 line++ ) {
00195 if ( ( *line ).startsWith( "Socket 0:" ) ) {
00196 if ( ( *line ).startsWith( "Socket 0: empty" ) && cardInPcmcia0 ) {
00197 cardInPcmcia0 = FALSE;
00198 } else if ( !( *line ).startsWith( "Socket 0: empty" )
00199 && !cardInPcmcia0 ) {
00200 cardInPcmcia0Name =
00201 ( *line ).mid( ( ( *line ).find( ':' ) + 1 ),
00202 ( *line ).length() - 9 );
00203 cardInPcmcia0Name.stripWhiteSpace();
00204 cardInPcmcia0 = TRUE;
00205 show();
00206 line++;
00207 int pos = ( *line ).find( '\t' ) + 1;
00208 cardInPcmcia0Type =
00209 ( *line ).mid( pos, ( *line ).find( "\t", pos ) - pos );
00210 }
00211 } else if ( ( *line ).startsWith( "Socket 1:" ) ) {
00212 if ( ( *line ).startsWith( "Socket 1: empty" ) && cardInPcmcia1 ) {
00213 cardInPcmcia1 = FALSE;
00214 } else if ( !( *line ).startsWith( "Socket 1: empty" )
00215 && !cardInPcmcia1 ) {
00216 cardInPcmcia1Name =
00217 ( *line ).mid( ( ( *line ).find( ':' ) + 1 ),
00218 ( *line ).length() - 9 );
00219 cardInPcmcia1Name.stripWhiteSpace();
00220 cardInPcmcia1 = TRUE;
00221 show();
00222 line++;
00223 int pos = ( *line ).find( '\t' ) + 1;
00224 cardInPcmcia1Type =
00225 ( *line ).mid( pos, ( *line ).find( "\t", pos ) - pos );
00226 }
00227 }
00228 }
00229 f.close();
00230
00231 if ( !showPopUp
00232 && ( cardWas0 != cardInPcmcia0 || cardWas1 != cardInPcmcia1 ) ) {
00233 QString text = QString::null;
00234 QString what = QString::null;
00235 if ( cardWas0 != cardInPcmcia0 ) {
00236 if ( cardInPcmcia0 ) {
00237 text += tr( "New card: " );
00238 what = "on";
00239 } else {
00240 text += tr( "Ejected: " );
00241 what = "off";
00242 }
00243 text += cardInPcmcia0Name;
00244 popUp( text, "cardmon/" + cardInPcmcia0Type );
00245 }
00246
00247 if ( cardWas1 != cardInPcmcia1 ) {
00248 if ( cardInPcmcia1 ) {
00249 text += tr( "New card: " );
00250 what = "on";
00251 } else {
00252 text += tr( "Ejected: " );
00253 what = "off";
00254 }
00255 text += cardInPcmcia1Name;
00256 popUp( text, "cardmon/" + cardInPcmcia1Type );
00257 }
00258 #ifndef QT_NO_SOUND
00259 QSound::play( Resource::findSound( "cardmon/card" + what ) );
00260 #endif
00261
00262 }
00263 } else {
00264
00265 odebug << "no file found" << oendl;
00266 cardInPcmcia0 = FALSE;
00267 cardInPcmcia1 = FALSE;
00268 }
00269 repaint( FALSE );
00270 return ( ( cardWas0 == cardInPcmcia0
00271 && cardWas1 == cardInPcmcia1 ) ? FALSE : TRUE );
00272
00273 }
00274
00275
00276 bool CardMonitor::getStatusSd( int showPopUp ) {
00277
00278 bool cardWas = cardInSd;
00279 cardInSd = FALSE;
00280
00281 #if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
00282
00283 struct mntent *me;
00284 FILE *mntfp = setmntent( "/etc/mtab", "r" );
00285
00286 if ( mntfp ) {
00287 while ( ( me = getmntent( mntfp ) ) != 0 ) {
00288 QString fs = QFile::decodeName( me->mnt_fsname );
00289
00290 if ( fs.left( 14 ) == "/dev/mmc/part1" || fs.left( 7 ) == "/dev/sd"
00291 || fs.left( 9 ) == "/dev/mmcd" || fs.left(11) == "/dev/mmcblk" ) {
00292 cardInSd = TRUE;
00293 cardSdName = fs;
00294 show();
00295 }
00296
00297
00298
00299 }
00300 endmntent( mntfp );
00301 }
00302
00303 if ( !showPopUp && cardWas != cardInSd ) {
00304 QString text = QString::null;
00305 QString what = QString::null;
00306 if ( cardInSd ) {
00307 text += tr("New card: SD/MMC");
00308 what = "on";
00309 } else {
00310 text += tr("Ejected: SD/MMC");
00311 what = "off";
00312 }
00313
00314 #ifndef QT_NO_SOUND
00315 QSound::play( Resource::findSound( "cardmon/card" + what ) );
00316 #endif
00317
00318 popUp( text, "cardmon/ide" );
00319 }
00320 #else
00321 #error "Not on Linux"
00322 #endif
00323 repaint( FALSE );
00324 return ( ( cardWas == cardInSd ) ? FALSE : TRUE );
00325 }
00326
00327 void CardMonitor::paintEvent( QPaintEvent * ) {
00328
00329 QPainter p( this );
00330
00331 if ( cardInPcmcia0 || cardInPcmcia1 || cardInSd ) {
00332 p.drawPixmap( 0, 0, pm );
00333 show();
00334 } else {
00335
00336 hide();
00337 }
00338 }
00339
00340 int CardMonitor::position() {
00341 return 7;
00342 }
00343
00344 void CardMonitor::execCommand( const QStringList &strList ) {
00345 delete m_process;
00346 m_process = 0;
00347
00348 if ( m_process == 0 ) {
00349 m_process = new OProcess();
00350
00351
00352 for ( QStringList::ConstIterator it = strList.begin(); it != strList.end(); ++it ) {
00353 *m_process << *it;
00354 }
00355
00356 connect(m_process, SIGNAL(processExited(Opie::Core::OProcess*)),
00357 this, SLOT( slotExited(Opie::Core::OProcess*)));
00358
00359 if(!m_process->start(OProcess::NotifyOnExit, OProcess::AllOutput ) ) {
00360 delete m_process;
00361 m_process = 0;
00362 }
00363 }
00364 }
00365
00366 void CardMonitor::slotExited( OProcess* ) {
00367
00368 if( m_process->normalExit() ) {
00369 int ret = m_process->exitStatus();
00370 if( ret != 0 ) {
00371 if ( m_commandOrig == PCMCIA_Socket1 ||
00372 m_commandOrig == PCMCIA_Socket2 ) {
00373 popUp( tr( "CF/PCMCIA card eject failed!" ) );
00374 } else if ( m_commandOrig == MMC_Socket ) {
00375 popUp( tr( "SD/MMC card eject failed!" ) );
00376 }
00377 }
00378 }
00379 }
00380
00381 EXPORT_OPIE_APPLET_v1( CardMonitor )
00382