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

irda.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2002 David Woodhouse <dwmw2@infradead.org>
00003 **                    Max Reiss <harlekin@handhelds.org> [trivial stuff]
00004 **                    Robert Griebl <sandman@handhelds.org>
00005 **                    Holger Freyther <zecke@handhelds.org> QCOP Interface
00006 **
00007 ** This file may be distributed and/or modified under the terms of the
00008 ** GNU General Public License version 2 as published by the Free Software
00009 ** Foundation and appearing in the file LICENSE.GPL included in the
00010 ** packaging of this file.
00011 **
00012 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 **
00015 **********************************************************************/
00016 
00017 #include "irda.h"
00018 
00019 /* OPIE */
00020 #include <opie2/oresource.h>
00021 #include <opie2/otaskbarapplet.h>
00022 
00023 #include <qpe/applnk.h>
00024 #include <qpe/qcopenvelope_qws.h>
00025 #include <qpe/ir.h>
00026 
00027 
00028 /* QT */
00029 #include <qpainter.h>
00030 #include <qfile.h>
00031 #include <qtimer.h>
00032 #include <qtextstream.h>
00033 
00034 /* STD */
00035 #include <unistd.h>
00036 #include <net/if.h>
00037 #include <netinet/in.h>
00038 #include <sys/types.h>
00039 #include <sys/socket.h>
00040 #include <sys/ioctl.h>
00041 
00042 //===========================================================================
00043 
00044 IrdaApplet::IrdaApplet ( QWidget *parent, const char *name )
00045                 : QWidget ( parent, name )
00046 {
00047     setFixedHeight( AppLnk::smallIconSize() );
00048     setFixedWidth( AppLnk::smallIconSize() );
00049 
00050     m_sockfd = ::socket ( PF_INET, SOCK_DGRAM, IPPROTO_IP );
00051 
00052     m_irdaOnPixmap = Opie::Core::OResource::loadPixmap( "irdaapplet/irdaon", Opie::Core::OResource::SmallIcon );
00053     m_irdaOffPixmap = Opie::Core::OResource::loadPixmap( "irdaapplet/irdaoff", Opie::Core::OResource::SmallIcon );
00054     m_irdaDiscoveryOnPixmap = Opie::Core::OResource::loadPixmap( "irdaapplet/magglass", Opie::Core::OResource::SmallIcon );
00055     m_receiveActivePixmap = Opie::Core::OResource::loadPixmap( "irdaapplet/receive", Opie::Core::OResource::SmallIcon );
00056 
00057         m_irda_active = false;
00058         m_irda_discovery_active = false;
00059         m_receive_active = false;
00060         m_receive_state_changed = false;
00061         m_popup = 0;
00062                 m_wasOn = false;
00063                 m_wasDiscover = false;
00064 
00065         QCopChannel* chan = new QCopChannel("QPE/IrDaApplet", this );
00066         connect(chan, SIGNAL(received(const QCString&,const QByteArray&) ),
00067                 this, SLOT(slotMessage(const QCString&,const QByteArray&) ) );
00068 }
00069 
00070 int IrdaApplet::position()
00071 {
00072         return 6;
00073 }
00074 
00075 void IrdaApplet::show()
00076 {
00077         QWidget::show ( );
00078         startTimer ( 2000 );
00079 }
00080 
00081 IrdaApplet::~IrdaApplet()
00082 {
00083         if ( m_sockfd >= 0 )
00084                 ::close ( m_sockfd );
00085 }
00086 
00087 void IrdaApplet::popup ( QString message, QString icon )
00088 {
00089         if ( !m_popup )
00090                 m_popup = new QPopupMenu ( this );
00091 
00092         m_popup-> clear ( );
00093 
00094         if ( icon. isEmpty ( ))
00095                 m_popup-> insertItem ( message, 0 );
00096         else
00097         m_popup-> insertItem ( QIconSet ( Opie::Core::OResource::loadPixmap ( icon, Opie::Core::OResource::SmallIcon )),
00098                                message, 0 );
00099 
00100         QPoint p = mapToGlobal ( QPoint ( 0, 0 ));
00101         QSize s = m_popup-> sizeHint ( );
00102         m_popup-> popup ( QPoint ( p. x ( ) + ( width ( ) / 2 ) - ( s. width ( ) / 2 ),
00103                                    p. y ( ) - s. height ( )));
00104 
00105         QTimer::singleShot ( 2000, this, SLOT( popupTimeout()));
00106 }
00107 
00108 void IrdaApplet::popupTimeout ( )
00109 {
00110         m_popup-> hide ( );
00111 }
00112 
00113 bool IrdaApplet::checkIrdaStatus ( )
00114 {
00115         struct ifreq ifr;
00116         strcpy ( ifr. ifr_name, "irda0" );
00117 
00118         if ( ::ioctl ( m_sockfd, SIOCGIFFLAGS, &ifr ) < 0 )
00119                 return false;
00120 
00121         return ( ifr. ifr_flags & IFF_UP );
00122 }
00123 
00124 bool IrdaApplet::setIrdaStatus ( bool b )
00125 {
00126         struct ifreq ifr;
00127         strcpy ( ifr. ifr_name, "irda0" );
00128 
00129         if ( ::ioctl ( m_sockfd, SIOCGIFFLAGS, &ifr ) < 0 )
00130                 return false;
00131 
00132         if ( b ) {
00133                 ifr. ifr_flags |= IFF_UP;
00134         }
00135         else {
00136                 setIrdaDiscoveryStatus ( 0 );
00137                 setIrdaReceiveStatus ( 0 );
00138                 ifr. ifr_flags &= ~IFF_UP;
00139         }
00140 
00141         if ( ::ioctl ( m_sockfd, SIOCSIFFLAGS, &ifr ) < 0 )
00142                 return false;
00143 
00144         return true;
00145 }
00146 
00147 bool IrdaApplet::checkIrdaDiscoveryStatus ( )
00148 {
00149         QFile discovery ( "/proc/sys/net/irda/discovery" );
00150 
00151         QString streamIn = "0";
00152 
00153         if ( discovery. open ( IO_ReadOnly )) {
00154                 QTextStream stream ( &discovery );
00155                 streamIn = stream. read ( );
00156         }
00157 
00158         return streamIn. toInt ( ) > 0;
00159 }
00160 
00161 
00162 bool IrdaApplet::setIrdaDiscoveryStatus ( bool d )
00163 {
00164         QFile discovery ( "/proc/sys/net/irda/discovery" );
00165 
00166         if ( discovery. open ( IO_WriteOnly | IO_Raw )) {
00167                 discovery.putch ( d ? '1' : '0' );
00168                 return true;
00169         }
00170         return false;
00171 }
00172 
00173 
00174 bool IrdaApplet::setIrdaReceiveStatus ( bool d )
00175 {
00176         QCopEnvelope e ( "QPE/Obex", "receive(int)" );
00177         e << ( d ? 1 : 0 );
00178 
00179         m_receive_active = d;
00180         m_receive_state_changed = true;
00181 
00182         return true;
00183 }
00184 
00185 
00186 void IrdaApplet::showDiscovered ( )
00187 {
00188 //      static Sound snd_found ( "irdaapplet/irdaon" );
00189 //      static Sound snd_lost ( "irdaapplet/irdaoff" );
00190 
00191         QFile discovery ( "/proc/net/irda/discovery" );
00192 
00193         if ( discovery. open ( IO_ReadOnly )) {
00194                 bool qcopsend = false;
00195 
00196                 QString discoveredDevice;
00197                 QString deviceAddr;
00198 
00199                 // since it is /proc we _must_ use QTextStream
00200                 QStringList list =  QStringList::split ( "\n", QTextStream ( &discovery ). read ( ));
00201 
00202                 QMap <QString, QString>::Iterator it;
00203 
00204                 for ( it = m_devices. begin ( ); it != m_devices. end ( ); ++it )
00205                         it. data ( ). prepend ( "+++" );
00206 
00207                 for ( QStringList::Iterator lit = list. begin ( ); lit != list. end ( ); ++lit ) {
00208                         const QString &line = *lit;
00209 
00210                         if ( line. startsWith ( "nickname:" )) {
00211                                 discoveredDevice = line. mid ( line. find ( ':' ) + 2, line. find ( ',' ) - line. find ( ':' ) - 2 );
00212                                 deviceAddr       = line. mid ( line. find ( "daddr:" ) + 9, 8 );
00213 
00214                                 // odebug << discoveredDevice + "(" + deviceAddr + ")" << oendl;
00215 
00216                                 if ( !m_devices. contains ( deviceAddr )) {
00217                                         popup ( tr( "Found:" ) + " " + discoveredDevice );
00218                                         //snd_found. play ( );
00219                                         qcopsend = true;
00220                                 }
00221                                 m_devices. replace ( deviceAddr, discoveredDevice );
00222                         }
00223                 }
00224 
00225                 for ( it = m_devices. begin ( ); it != m_devices. end ( ); ) {
00226                         // odebug << "IrdaMon: delete " + it.currentKey() + "=" + *devicesAvailable[it.currentKey()] + "?" << oendl;
00227 
00228                         if ( it. data ( ). left ( 3 ) == "+++" ) {
00229                                 popup ( tr( "Lost:" ) + " " + it. data ( ). mid ( 3 ));
00230                                 //snd_lost. play ( );
00231 
00232                                 QMap <QString, QString>::Iterator tmp = it;
00233                                 tmp++;
00234                                 m_devices. remove ( it ); // in contrast to QValueListIterator this remove doesn't return the next Iterator
00235                                 it = tmp;
00236 
00237                                 qcopsend = true;
00238                         }
00239                         else
00240                                 it++;
00241                 }
00242                 // XXX if( qcopsend ) {
00243                     QCopEnvelope e ( "QPE/Network", "irdaSend(bool)" );
00244                     e << ( m_devices. count ( ) > 0 );
00245                 // }
00246         }
00247 }
00248 
00249 void IrdaApplet::mousePressEvent ( QMouseEvent * )
00250 {
00251         QPopupMenu *menu = new QPopupMenu ( this );
00252         QString cmd;
00253 
00254         /* Refresh active state */
00255         timerEvent ( 0 );
00256 
00257         //      menu->insertItem( tr("More..."), 4 );
00258 
00259         if ( m_irda_active && !m_devices. isEmpty ( )) {
00260                 menu-> insertItem ( tr( "Discovered Device:" ), 9 );
00261 
00262                 for ( QMap<QString, QString>::Iterator it = m_devices. begin ( ); it != m_devices. end ( ); ++it )
00263                         menu-> insertItem ( *it );
00264 
00265                 menu-> insertSeparator ( );
00266         }
00267 
00268         menu-> insertItem ( m_irda_active ? tr( "Disable IrDA" ) : tr( "Enable IrDA" ), 0 );
00269 
00270         if ( m_irda_active ) {
00271                 menu-> insertItem ( m_irda_discovery_active ? tr( "Disable Discovery" ) : tr( "Enable Discovery" ), 1 );
00272                 
00273                 /* Only Receive if OBEX is installed */
00274                 if( Ir::supported() )
00275                         menu-> insertItem ( m_receive_active ? tr( "Disable Receive" ) : tr( "Enable Receive" ), 2 );
00276         }
00277 
00278         QPoint p = mapToGlobal ( QPoint ( 0, 0 ) );
00279         QSize s = menu-> sizeHint ( );
00280 
00281         p = QPoint ( p. x ( ) + ( width ( ) / 2 ) - ( s. width ( ) / 2 ), p. y ( ) - s. height ( ));
00282 
00283         switch (  menu-> exec ( p )) {
00284                 case 0:
00285                         setIrdaStatus ( !m_irda_active );
00286                         timerEvent ( 0 );
00287                         break;
00288                 case 1:
00289                         setIrdaDiscoveryStatus ( !m_irda_discovery_active );
00290                         timerEvent ( 0 );
00291                         break;
00292                 case 2:
00293                         setIrdaReceiveStatus ( !m_receive_active );
00294                         timerEvent( 0 );
00295                         break;
00296         }
00297 
00298         delete menu;
00299 }
00300 
00301 void IrdaApplet::timerEvent ( QTimerEvent * )
00302 {
00303         bool oldactive = m_irda_active;
00304         bool olddiscovery = m_irda_discovery_active;
00305         bool receiveUpdate = false;
00306 
00307         if ( m_receive_state_changed ) {
00308                 receiveUpdate = true;
00309                 m_receive_state_changed = false;
00310         }
00311 
00312         m_irda_active = checkIrdaStatus ( );
00313         m_irda_discovery_active = checkIrdaDiscoveryStatus ( );
00314 
00315         if ( m_irda_discovery_active )
00316                 showDiscovered ( );
00317 
00318         if (( m_irda_active != oldactive ) || ( m_irda_discovery_active != olddiscovery ) || receiveUpdate )
00319                 update ( );
00320 }
00321 
00322 void IrdaApplet::paintEvent ( QPaintEvent * )
00323 {
00324         QPainter p( this );
00325 
00326         p.drawPixmap( 0, 1, m_irda_active ? m_irdaOnPixmap : m_irdaOffPixmap );
00327 
00328         if ( m_irda_discovery_active )
00329                 p.drawPixmap( 0, 1, m_irdaDiscoveryOnPixmap );
00330 
00331         if ( m_receive_active )
00332                 p.drawPixmap( 0, 1, m_receiveActivePixmap );
00333 }
00334 /*
00335  * We know 3 calls
00336  * a) enable
00337  * b) disable
00338  * a and b will temp enable the IrDa device and disable will disable it again if it wasn't on
00339  * c) listDevices: We will return a list of known devices
00340  */
00341 void IrdaApplet::slotMessage( const QCString& str, const QByteArray&  ) {
00342     if ( str == "enableIrda()") {
00343         m_wasOn = checkIrdaStatus();
00344         m_wasDiscover = checkIrdaDiscoveryStatus();
00345         if (!m_wasOn)  {
00346             setIrdaStatus( true );
00347         }
00348         if ( !m_wasDiscover ) {
00349             setIrdaDiscoveryStatus ( true );
00350         }
00351     } else if ( str == "disableIrda()") {
00352         if (!m_wasOn)  {
00353             setIrdaStatus( false );
00354         }
00355         if ( !m_wasDiscover ) {
00356             setIrdaDiscoveryStatus ( false );
00357         }
00358     } else if ( str == "listDevices()") {
00359         QCopEnvelope e("QPE/IrDaAppletBack", "devices(QStringList)");
00360 
00361         QStringList list;
00362         QMap<QString, QString>::Iterator it;
00363         for (it = m_devices.begin(); it != m_devices.end(); ++it )
00364             list << (*it);
00365 
00366         e << list;
00367     }
00368 }
00369 
00370 EXPORT_OPIE_APPLET_v1( IrdaApplet )

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