summaryrefslogtreecommitdiff
path: root/core/applets/irdaapplet/irda.cpp
authorsandman <sandman>2002-06-27 12:56:22 (UTC)
committer sandman <sandman>2002-06-27 12:56:22 (UTC)
commit56d22ac17fdc194a20fd0deba673943f85e940ea (patch) (unidiff)
tree564c333bfa77e1dbae9a553e2c208eecefdeea1e /core/applets/irdaapplet/irda.cpp
parent88b644d1c106008fc15f6a3c496e40296e9029d4 (diff)
downloadopie-56d22ac17fdc194a20fd0deba673943f85e940ea.zip
opie-56d22ac17fdc194a20fd0deba673943f85e940ea.tar.gz
opie-56d22ac17fdc194a20fd0deba673943f85e940ea.tar.bz2
Fix an endless loop error when device is lost.
Diffstat (limited to 'core/applets/irdaapplet/irda.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/applets/irdaapplet/irda.cpp502
1 files changed, 223 insertions, 279 deletions
diff --git a/core/applets/irdaapplet/irda.cpp b/core/applets/irdaapplet/irda.cpp
index 42bed5e..c3ddff2 100644
--- a/core/applets/irdaapplet/irda.cpp
+++ b/core/applets/irdaapplet/irda.cpp
@@ -1,7 +1,7 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2002 David Woodhouse <dwmw2@infradead.org> 2** Copyright (C) 2002 David Woodhouse <dwmw2@infradead.org>
3** Heavily based on volumeapplet, (C) 2002 L.J. Potter ljp@llornkcor.com 3** Max Reiss <harlekin@handhelds.org> [trivial stuff]
4** All rights reserved. 4** Robert Griebl <sandman@handhelds.org>
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
@@ -13,357 +13,301 @@
13** 13**
14**********************************************************************/ 14**********************************************************************/
15 15
16#include "irda.h"
17#include <qapplication.h>
18#include <stdlib.h>
19
20
21#include <qpe/resource.h>
22#include <qpe/qpeapplication.h> 16#include <qpe/qpeapplication.h>
23#include <qpe/timestring.h>
24#include <qpe/resource.h> 17#include <qpe/resource.h>
25#include <qpe/config.h>
26#include <qpe/applnk.h>
27#include <qpe/config.h>
28#include <qpe/ir.h> 18#include <qpe/ir.h>
29#include <qpe/qcopenvelope_qws.h> 19#include <qpe/qcopenvelope_qws.h>
20#include <qpe/sound.h>
30 21
31#include <qdir.h>
32#include <qfileinfo.h>
33#include <qpoint.h>
34#include <qpushbutton.h>
35#include <qpainter.h> 22#include <qpainter.h>
36#include <qcombobox.h>
37#include <qspinbox.h>
38#include <qslider.h>
39#include <qlayout.h>
40#include <qframe.h>
41#include <qpixmap.h>
42#include <qstring.h>
43#include <qfile.h> 23#include <qfile.h>
44#include <qtimer.h> 24#include <qtimer.h>
45#include <qtextstream.h> 25#include <qtextstream.h>
46#include <qpopupmenu.h> 26#include <qpopupmenu.h>
47#include <qsound.h>
48 27
28#include <unistd.h>
49#include <net/if.h> 29#include <net/if.h>
50#include <netinet/in.h> 30#include <netinet/in.h>
51#include <sys/types.h> 31#include <sys/types.h>
52#include <sys/socket.h> 32#include <sys/socket.h>
53#include <sys/ioctl.h> 33#include <sys/ioctl.h>
54 34
35#include "irda.h"
55 36
56//=========================================================================== 37//===========================================================================
57 38
58IrdaApplet::IrdaApplet( QWidget *parent, const char *name ) 39IrdaApplet::IrdaApplet ( QWidget *parent, const char *name )
59 : QWidget( parent, name ) { 40 : QWidget ( parent, name )
60 setFixedHeight( 14 ); 41{
61 setFixedWidth( 14 ); 42 setFixedHeight ( 18 );
62 sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); 43 setFixedWidth ( 14 );
63 irdaOnPixmap = Resource::loadPixmap( "irdaapplet/irdaon" ); 44
64 irdaOffPixmap = Resource::loadPixmap( "irdaapplet/irdaoff" ); 45 m_sockfd = ::socket ( PF_INET, SOCK_DGRAM, IPPROTO_IP );
65 irdaDiscoveryOnPixmap = Resource::loadPixmap( "irdaapplet/magglass" ); 46
66 receiveActivePixmap = Resource::loadPixmap("irdaapplet/receive"); 47 m_irdaOnPixmap = Resource::loadPixmap( "irdaapplet/irdaon" );
67 receiveActive = false; 48 m_irdaOffPixmap = Resource::loadPixmap( "irdaapplet/irdaoff" );
68 popupMenu = 0; 49 m_irdaDiscoveryOnPixmap = Resource::loadPixmap( "irdaapplet/magglass" );
69 devicesAvailable.setAutoDelete(TRUE); 50 m_receiveActivePixmap = Resource::loadPixmap( "irdaapplet/receive" );
51
52 m_irda_active = false;
53 m_irda_discovery_active = false;
54 m_receive_active = false;
55 m_receive_state_changed = false;
56 m_popup = 0;
70} 57}
71 58
72void IrdaApplet::show() { 59void IrdaApplet::show()
73 QWidget::show(); 60{
74 startTimer(2000); 61 QWidget::show ( );
62 startTimer ( 2000 );
75} 63}
76 64
77IrdaApplet::~IrdaApplet() { 65IrdaApplet::~IrdaApplet()
78 close(sockfd); 66{
79 if( popupMenu ) { delete popupMenu; } 67 if ( m_sockfd >= 0 )
68 ::close ( m_sockfd );
80} 69}
81 70
82void IrdaApplet::popup(QString message, QString icon="") { 71void IrdaApplet::popup ( QString message, QString icon )
83 if ( ! popupMenu ) { 72{
84 popupMenu = new QPopupMenu(); 73 if ( !m_popup )
85 } 74 m_popup = new QPopupMenu ( this );
86 popupMenu->clear(); 75
87 if( icon == "" ) { 76 m_popup-> clear ( );
88 popupMenu->insertItem( message, 0 ); 77
89 } else { 78 if ( icon. isEmpty ( ))
90 popupMenu->insertItem( QIconSet ( Resource::loadPixmap ( icon )), 79 m_popup-> insertItem ( message, 0 );
91 message, 0 ); 80 else
92 } 81 m_popup-> insertItem ( QIconSet ( Resource::loadPixmap ( icon )), message, 0 );
93 82
94 QPoint p = mapToGlobal ( QPoint ( 0, 0 )); 83 QPoint p = mapToGlobal ( QPoint ( 0, 0 ));
95 QSize s = popupMenu->sizeHint ( ); 84 QSize s = m_popup-> sizeHint ( );
96 popupMenu->popup( QPoint ( 85 m_popup-> popup ( QPoint ( p. x ( ) + ( width ( ) / 2 ) - ( s. width ( ) / 2 ),
97 p. x ( ) + ( width ( ) / 2 ) - ( s. width ( ) / 2 ), 86 p. y ( ) - s. height ( )));
98 p. y ( ) - s. height ( ) ), 0);
99
100 QTimer::singleShot( 2000, this, SLOT(popupTimeout()) );
101}
102 87
103void IrdaApplet::popupTimeout() { 88 QTimer::singleShot ( 2000, this, SLOT( popupTimeout ( )));
104 popupMenu->hide();
105} 89}
106 90
107int IrdaApplet::checkIrdaStatus() { 91void IrdaApplet::popupTimeout ( )
108 struct ifreq ifr; 92{
93 m_popup-> hide ( );
94}
109 95
110 strcpy(ifr.ifr_name, "irda0"); 96bool IrdaApplet::checkIrdaStatus ( )
97{
98 struct ifreq ifr;
99 strcpy ( ifr. ifr_name, "irda0" );
111 100
112 if (ioctl(sockfd, SIOCGIFFLAGS, &ifr)) 101 if ( ::ioctl ( m_sockfd, SIOCGIFFLAGS, &ifr ) < 0 )
113 return -1; 102 return false;
114 103
115 return (ifr.ifr_flags & IFF_UP)?1:0; 104 return ( ifr. ifr_flags & IFF_UP );
116} 105}
117 106
118int IrdaApplet::setIrdaStatus(int c) { 107bool IrdaApplet::setIrdaStatus ( bool b )
119 struct ifreq ifr; 108{
120 109 struct ifreq ifr;
121 strcpy(ifr.ifr_name, "irda0"); 110 strcpy ( ifr. ifr_name, "irda0" );
122 111
123 if (ioctl(sockfd, SIOCGIFFLAGS, &ifr)) 112 if ( ::ioctl ( m_sockfd, SIOCGIFFLAGS, &ifr ) < 0 )
124 return -1; 113 return false;
125 114
126 if (c) { 115 if ( b ) {
127 ifr.ifr_flags |= IFF_UP; 116 ifr. ifr_flags |= IFF_UP;
128 } else { 117 }
129 setIrdaDiscoveryStatus(0); 118 else {
130 setIrdaReceiveStatus(0); 119 setIrdaDiscoveryStatus ( 0 );
131 ifr.ifr_flags &= ~IFF_UP; 120 setIrdaReceiveStatus ( 0 );
132 } 121 ifr. ifr_flags &= ~IFF_UP;
122 }
133 123
134 if (ioctl(sockfd, SIOCSIFFLAGS, &ifr)) 124 if ( ::ioctl ( m_sockfd, SIOCSIFFLAGS, &ifr ) < 0 )
135 return -1; 125 return false;
136 126
137 return 0; 127 return true;
138} 128}
139 129
140int IrdaApplet::checkIrdaDiscoveryStatus() { 130bool IrdaApplet::checkIrdaDiscoveryStatus ( )
131{
132 QFile discovery ( "/proc/sys/net/irda/discovery" );
133
134 QString streamIn = "0";
135
136 if ( discovery. open ( IO_ReadOnly )) {
137 QTextStream stream ( &discovery );
138 streamIn = stream. read ( );
139 }
140
141 return streamIn. toInt ( ) > 0;
142}
141 143
142 QFile discovery("/proc/sys/net/irda/discovery");
143 144
144 QString streamIn = "0"; 145bool IrdaApplet::setIrdaDiscoveryStatus ( bool d )
146{
147 QFile discovery ( "/proc/sys/net/irda/discovery" );
145 148
146 if (discovery.open(IO_ReadOnly) ) { 149 if ( discovery. open ( IO_WriteOnly | IO_Raw )) {
147 QTextStream stream ( &discovery ); 150 discovery.putch ( d ? '1' : '0' );
148 streamIn = stream.read(); 151 return true;
149 } 152 }
153 return false;
154}
150 155
151 discovery.close();
152 156
153 return( streamIn.toInt() ); 157bool IrdaApplet::setIrdaReceiveStatus ( bool d )
158{
159 QCopEnvelope e ( "QPE/Obex", "receive(int)" );
160 e << ( d ? 1 : 0 );
161
162 m_receive_active = d;
163 m_receive_state_changed = true;
164
165 return true;
154} 166}
155 167
156 168
157int IrdaApplet::setIrdaDiscoveryStatus(int d) { 169void IrdaApplet::showDiscovered ( )
158 QFile discovery("/proc/sys/net/irda/discovery"); 170{
171 static Sound snd_found ( "irdaapplet/irdaon" );
172 static Sound snd_lost ( "irdaapplet/irdaoff" );
159 173
160 discovery.open( IO_WriteOnly|IO_Raw ); 174 QFile discovery ( "/proc/net/irda/discovery" );
161 175
162 if (d) 176 if ( discovery. open ( IO_ReadOnly )) {
163 discovery.putch('1'); 177 bool qcopsend = false;
164 else
165 discovery.putch('0');
166 178
167 discovery.close(); 179 QString discoveredDevice;
180 QString deviceAddr;
181
182 // since it is /proc we _must_ use QTextStream
183 QStringList list = QStringList::split ( "\n", QTextStream ( &discovery ). read ( ));
168 184
169 return 0; 185 QMap <QString, QString>::Iterator it;
170}
171 186
172int IrdaApplet::setIrdaReceiveStatus(int d) { 187 for ( it = m_devices. begin ( ); it != m_devices. end ( ); ++it )
173 if(d) { 188 it. data ( ). prepend ( "+++" );
174 qWarning("Enable receive" );
175 QCopEnvelope e("QPE/Obex", "receive(int)" );
176 e << 1;
177 receiveActive = true;
178 receiveStateChanged = true;
179 } else {
180 qWarning("Disable receive" );
181 QCopEnvelope e("QPE/Obex", "receive(int)" );
182 e << 0;
183 receiveActive = false;
184 receiveStateChanged = true;
185 }
186 return 0;
187}
188 189
189void IrdaApplet::showDiscovered() { 190 for ( QStringList::Iterator lit = list. begin ( ); lit != list. end ( ); ++lit ) {
190 QFile discovery("/proc/net/irda/discovery"); 191 const QString &line = *lit;
191 192
192 if (discovery.open(IO_ReadOnly) ) { 193 if ( line. startsWith ( "nickname:" )) {
193 int qcopsend = FALSE; 194 discoveredDevice = line. mid ( line. find ( ':' ) + 2, line. find ( ',' ) - line. find ( ':' ) - 2 );
194 195 deviceAddr = line. mid ( line. find ( "daddr:" ) + 9, 8 );
195 QString discoveredDevice;
196 QString deviceAddr;
197 QStringList list;
198 // since it is /proc we _must_ use QTextStream
199 QTextStream stream ( &discovery);
200 QString streamIn;
201 streamIn = stream.read();
202 list = QStringList::split("\n", streamIn);
203
204 QDictIterator<QString> it( devicesAvailable );
205 while ( it.current() ) {
206 devicesAvailable.replace( it.currentKey(), new QString("+++" + *devicesAvailable[it.currentKey()]) );
207 //qDebug("IrdaMon: " + it.currentKey());
208 //qDebug(" =" + *devicesAvailable[it.currentKey()] );
209 ++it;
210 }
211 196
212 for(QStringList::Iterator line=list.begin(); line!=list.end(); line++) { 197 // qDebug(discoveredDevice + "(" + deviceAddr + ")");
213 // qDebug( (*line) );
214 if( (*line).startsWith("nickname:") ){
215 discoveredDevice = (*line).mid(((*line).find(':'))+2,(*line).find(',')-(*line).find(':')-2);
216 deviceAddr = (*line).mid( (*line).find( "daddr:" )+9, 8 );
217 198
218 // qDebug(discoveredDevice + "(" + deviceAddr + ")"); 199 if ( !m_devices. contains ( deviceAddr )) {
200 popup ( tr( "Found:" ) + " " + discoveredDevice );
201 snd_found. play ( );
202 qcopsend = true;
203 }
204 m_devices. replace ( deviceAddr, discoveredDevice );
205 }
206 }
219 207
220 if( ! devicesAvailable.find(deviceAddr) ) { 208 for ( it = m_devices. begin ( ); it != m_devices. end ( ); ) {
221 popup( tr("Found:") + " " + discoveredDevice ); 209 // qDebug("IrdaMon: delete " + it.currentKey() + "=" + *devicesAvailable[it.currentKey()] + "?");
222 QSound::play(Resource::findSound("irdaapplet/irdaon")); 210
223 qcopsend = TRUE; 211 if ( it. data ( ). left ( 3 ) == "+++" ) {
212 popup ( tr( "Lost:" ) + " " + it. data ( ). mid ( 3 ));
213 snd_lost. play ( );
214
215 QMap <QString, QString>::Iterator tmp = it;
216 tmp++;
217 m_devices. remove ( it ); // in contrast to QValueListIterator this remove doesn't return the next Iterator
218 it = tmp;
219
220 qcopsend = true;
221 }
222 else
223 it++;
224 } 224 }
225 devicesAvailable.replace( deviceAddr, new QString(discoveredDevice) ); 225 // XXX if( qcopsend ) {
226 // qDebug("IrdaMon: " + deviceAddr + "=" + *devicesAvailable[deviceAddr] ); 226 QCopEnvelope e ( "QPE/Network", "irdaSend(bool)" );
227 } 227 e << ( m_devices. count ( ) > 0 );
228 } 228 // }
229
230 it.toFirst();
231 while ( it.current() ) {
232 // qDebug("IrdaMon: delete " + it.currentKey() + "=" + *devicesAvailable[it.currentKey()] + "?");
233 if ( (*it.current()).left(3) == "+++" ) {
234 popup( tr("Lost:") + " " + (*devicesAvailable[it.currentKey()]).mid(3) );
235 QSound::play(Resource::findSound("irdaapplet/irdaoff"));
236 devicesAvailable.remove( it.currentKey() );
237 // qDebug("IrdaMon: delete " + it.currentKey() + "!");
238 qcopsend = TRUE;
239 }
240 ++it;
241 } 229 }
242 /* XXX if( qcopsend ) {
243 QCopEnvelope e("QPE/Network", "irdaSend(bool)" );
244 e << (devicesAvailable.count() > 0) ;
245 } */
246 }
247} 230}
248 231
249void IrdaApplet::mousePressEvent( QMouseEvent *) { 232void IrdaApplet::mousePressEvent ( QMouseEvent * )
250 QPopupMenu *menu = new QPopupMenu(); 233{
251 QString cmd; 234 QPopupMenu *menu = new QPopupMenu ( this );
252 int ret=0; 235 QString cmd;
236
237 /* Refresh active state */
238 timerEvent ( 0 );
253 239
254 /* Refresh active state */ 240 //menu->insertItem( tr("More..."), 4 );
255 timerEvent(NULL);
256 241
257 //menu->insertItem( tr("More..."), 4 ); 242 if ( m_irda_active && !m_devices. isEmpty ( )) {
243 menu-> insertItem ( tr( "Discovered Device:" ), 9 );
258 244
259 if (irdaactive && devicesAvailable.count() > 0) { 245 for ( QMap<QString, QString>::Iterator it = m_devices. begin ( ); it != m_devices. end ( ); ++it )
260 menu->insertItem( tr("Discovered Device:"), 9); 246 menu-> insertItem ( *it );
261 QDictIterator<QString> it( devicesAvailable ); 247
262 while ( it.current() ) { 248 menu-> insertSeparator ( );
263 menu->insertItem( *devicesAvailable[it.currentKey()]);
264 ++it;
265 } 249 }
266 menu->insertSeparator(); 250
267 } 251 menu-> insertItem ( m_irda_active ? tr( "Disable IrDA" ) : tr( "Enable IrDA" ), 0 );
268 252
269 if (irdaactive) { 253 if ( m_irda_active ) {
270 menu->insertItem( tr("Disable IrDA"), 0 ); 254 menu-> insertItem ( m_irda_discovery_active ? tr( "Disable Discovery" ) : tr( "Enable Discovery" ), 1 );
271 } else { 255 menu-> insertItem ( m_receive_active ? tr( "Disable Receive" ) : tr( "Enable Receive" ), 2 );
272 menu->insertItem( tr("Enable IrDA"), 1 );
273 }
274
275 if (irdaactive) {
276 if (irdaDiscoveryActive) {
277 menu->insertItem( tr("Disable Discovery"), 2 );
278 } else {
279 menu->insertItem( tr("Enable Discovery"), 3 );
280 } 256 }
281 257
282 if( receiveActive ){ 258 QPoint p = mapToGlobal ( QPoint ( 0, 0 ) );
283 menu->insertItem( tr("Disable Receive"), 4 ); 259 QSize s = menu-> sizeHint ( );
284 } else { 260
285 menu->insertItem( tr("Enable Receive"), 5 ); 261 p = QPoint ( p. x ( ) + ( width ( ) / 2 ) - ( s. width ( ) / 2 ), p. y ( ) - s. height ( ));
262
263 switch ( menu-> exec ( p )) {
264 case 0:
265 setIrdaStatus ( !m_irda_active );
266 timerEvent ( 0 );
267 break;
268 case 1:
269 setIrdaDiscoveryStatus ( !m_irda_discovery_active );
270 timerEvent ( 0 );
271 break;
272 case 2:
273 setIrdaReceiveStatus ( !m_receive_active );
274 timerEvent( 0 );
275 break;
286 } 276 }
287 } 277
288 278 delete menu;
289 QPoint p = mapToGlobal ( QPoint ( 0, 0 ));
290 QSize s = menu-> sizeHint ( );
291 ret = menu->exec( QPoint (
292 p. x ( ) + ( width ( ) / 2 ) - ( s. width ( ) / 2 ),
293 p. y ( ) - s. height ( ) ), 0);
294
295 // qDebug("ret was %d\n", ret);
296
297 switch(ret) {
298 case 0:
299 setIrdaStatus(0);
300 timerEvent(NULL);
301 break;
302 case 1:
303 setIrdaStatus(1);
304 timerEvent(NULL);
305 break;
306 case 2:
307 setIrdaDiscoveryStatus(0);
308 timerEvent(NULL);
309 break;
310 case 3:
311 setIrdaDiscoveryStatus(1);
312 timerEvent(NULL); // NULL is undefined in c++ use 0 or 0l
313 break;
314 case 4: { // enable receive
315 setIrdaReceiveStatus(0);
316 timerEvent(NULL);
317 break;
318 }
319 case 5: { // disable receive
320 setIrdaReceiveStatus(1);
321 timerEvent(NULL);
322 break;
323 }
324 }
325 delete menu; // Can somebody explain why use a QPopupMenu* and not QPopupMenu nor QAction. with out delete we will leak cause QPopupMenu doesn't have a parent in this case
326} 279}
327 280
328void IrdaApplet::timerEvent( QTimerEvent * ) { 281void IrdaApplet::timerEvent ( QTimerEvent * )
329 int oldactive = irdaactive; 282{
330 int olddiscovery = irdaDiscoveryActive; 283 bool oldactive = m_irda_active;
331 bool receiveUpdate = false; 284 bool olddiscovery = m_irda_discovery_active;
332 285 bool receiveUpdate = false;
333 if (receiveStateChanged) {
334 receiveUpdate = true;
335 receiveStateChanged = false;
336 }
337 286
338 irdaactive = checkIrdaStatus(); 287 if ( m_receive_state_changed ) {
339 irdaDiscoveryActive = checkIrdaDiscoveryStatus(); 288 receiveUpdate = true;
289 m_receive_state_changed = false;
290 }
340 291
341 292 m_irda_active = checkIrdaStatus ( );
342 if (irdaDiscoveryActive) { 293 m_irda_discovery_active = checkIrdaDiscoveryStatus ( );
343 showDiscovered();
344 }
345 294
346 if ((irdaactive != oldactive) || (irdaDiscoveryActive != olddiscovery) || receiveUpdate ) { 295 if ( m_irda_discovery_active )
347 paintEvent(NULL); 296 showDiscovered ( );
348 }
349 297
298 if (( m_irda_active != oldactive ) || ( m_irda_discovery_active != olddiscovery ) || receiveUpdate )
299 update ( );
350} 300}
351 301
352void IrdaApplet::paintEvent( QPaintEvent* ) { 302void IrdaApplet::paintEvent ( QPaintEvent * )
353 QPainter p(this); 303{
354 // qDebug("paint irda pixmap"); 304 QPainter p ( this );
355 305
356 p.eraseRect ( 0, 0, this->width(), this->height() ); 306 p. drawPixmap ( 0, 1, m_irda_active ? m_irdaOnPixmap : m_irdaOffPixmap );
357 if (irdaactive > 0) { 307
358 p.drawPixmap( 0, 0, irdaOnPixmap ); 308 if ( m_irda_discovery_active )
359 } else { 309 p. drawPixmap( 0, 1, m_irdaDiscoveryOnPixmap );
360 p.drawPixmap( 0, 0, irdaOffPixmap ); 310
361 } 311 if ( m_receive_active )
362 312 p. drawPixmap( 0, 1, m_receiveActivePixmap );
363 if (irdaDiscoveryActive > 0) {
364 p.drawPixmap( 0, 0, irdaDiscoveryOnPixmap );
365 }
366 if (receiveActive) {
367 p.drawPixmap( 0, 0, receiveActivePixmap);
368 }
369} 313}