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

cardmon.cpp

Go to the documentation of this file.
00001 /*
00002 * cardmon.cpp
00003 *
00004 * ---------------------
00005 *
00006 * copyright   : (c) 2002 by Maximilian Reiss
00007 * email       : max.reiss@gmx.de
00008 * based on two apps by Devin Butterfield
00009 */
00010 /***************************************************************************
00011  *                                                                         *
00012  *   This program is free software; you can redistribute it and/or modify  *
00013  *   it under the terms of the GNU General Public License as published by  *
00014  *   the Free Software Foundation; either version 2 of the License, or     *
00015  *   (at your option) any later version.                                   *
00016  *                                                                         *
00017  ***************************************************************************/
00018 
00019 #include "cardmon.h"
00020 
00021 /* OPIE */
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 /* QT */
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 /* STD */
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         // odebug << "Pcmcia: stabchanged" << oendl;
00162         getStatusPcmcia();
00163     } else if ( msg == "mtabChanged()" ) {
00164         // odebug << "CARDMONAPPLET: mtabchanged" << oendl;
00165         getStatusSd();
00166     }
00167 }
00168 
00169 bool CardMonitor::getStatusPcmcia( int showPopUp ) {
00170 
00171     bool cardWas0 = cardInPcmcia0;    // remember last state
00172     bool cardWas1 = cardInPcmcia1;
00173 
00174     QString fileName;
00175 
00176     // one of these 3 files should exist
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         // no file found
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;    // remember last state
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             //odebug << fs << oendl;
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             //            else {
00297             //                 cardInSd = FALSE;
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         //odebug << "TEXT: " + text << oendl;
00314         #ifndef QT_NO_SOUND
00315         QSound::play( Resource::findSound( "cardmon/card" + what ) );
00316         #endif
00317 
00318         popUp( text, "cardmon/ide" );    // XX add SD pic
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         //p.eraseRect(rect());
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 

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