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) (show whitespace changes)
-rw-r--r--core/applets/irdaapplet/irda.cpp376
1 files changed, 160 insertions, 216 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,132 +13,122 @@
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{
42 setFixedHeight ( 18 );
61 setFixedWidth( 14 ); 43 setFixedWidth( 14 );
62 sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); 44
63 irdaOnPixmap = Resource::loadPixmap( "irdaapplet/irdaon" ); 45 m_sockfd = ::socket ( PF_INET, SOCK_DGRAM, IPPROTO_IP );
64 irdaOffPixmap = Resource::loadPixmap( "irdaapplet/irdaoff" ); 46
65 irdaDiscoveryOnPixmap = Resource::loadPixmap( "irdaapplet/magglass" ); 47 m_irdaOnPixmap = Resource::loadPixmap( "irdaapplet/irdaon" );
66 receiveActivePixmap = Resource::loadPixmap("irdaapplet/receive"); 48 m_irdaOffPixmap = Resource::loadPixmap( "irdaapplet/irdaoff" );
67 receiveActive = false; 49 m_irdaDiscoveryOnPixmap = Resource::loadPixmap( "irdaapplet/magglass" );
68 popupMenu = 0; 50 m_receiveActivePixmap = Resource::loadPixmap( "irdaapplet/receive" );
69 devicesAvailable.setAutoDelete(TRUE); 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()
60{
73 QWidget::show(); 61 QWidget::show();
74 startTimer(2000); 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 87
100 QTimer::singleShot( 2000, this, SLOT(popupTimeout()) ); 88 QTimer::singleShot( 2000, this, SLOT(popupTimeout()) );
101} 89}
102 90
103void IrdaApplet::popupTimeout() { 91void IrdaApplet::popupTimeout ( )
104 popupMenu->hide(); 92{
93 m_popup-> hide ( );
105} 94}
106 95
107int IrdaApplet::checkIrdaStatus() { 96bool IrdaApplet::checkIrdaStatus ( )
97{
108 struct ifreq ifr; 98 struct ifreq ifr;
109
110 strcpy(ifr.ifr_name, "irda0"); 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 )
108{
119 struct ifreq ifr; 109 struct ifreq ifr;
120
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 }
118 else {
129 setIrdaDiscoveryStatus(0); 119 setIrdaDiscoveryStatus(0);
130 setIrdaReceiveStatus(0); 120 setIrdaReceiveStatus(0);
131 ifr.ifr_flags &= ~IFF_UP; 121 ifr.ifr_flags &= ~IFF_UP;
132 } 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 ( )
141 131{
142 QFile discovery("/proc/sys/net/irda/discovery"); 132 QFile discovery("/proc/sys/net/irda/discovery");
143 133
144 QString streamIn = "0"; 134 QString streamIn = "0";
@@ -148,222 +138,176 @@ int IrdaApplet::checkIrdaDiscoveryStatus() {
148 streamIn = stream.read(); 138 streamIn = stream.read();
149 } 139 }
150 140
151 discovery.close(); 141 return streamIn. toInt ( ) > 0;
152
153 return( streamIn.toInt() );
154} 142}
155 143
156 144
157int IrdaApplet::setIrdaDiscoveryStatus(int d) { 145bool IrdaApplet::setIrdaDiscoveryStatus ( bool d )
146{
158 QFile discovery("/proc/sys/net/irda/discovery"); 147 QFile discovery("/proc/sys/net/irda/discovery");
159 148
160 discovery.open( IO_WriteOnly|IO_Raw ); 149 if ( discovery. open ( IO_WriteOnly | IO_Raw )) {
150 discovery.putch ( d ? '1' : '0' );
151 return true;
152 }
153 return false;
154}
161 155
162 if (d)
163 discovery.putch('1');
164 else
165 discovery.putch('0');
166 156
167 discovery.close(); 157bool IrdaApplet::setIrdaReceiveStatus ( bool d )
158{
159 QCopEnvelope e ( "QPE/Obex", "receive(int)" );
160 e << ( d ? 1 : 0 );
168 161
169 return 0; 162 m_receive_active = d;
170} 163 m_receive_state_changed = true;
171 164
172int IrdaApplet::setIrdaReceiveStatus(int d) { 165 return true;
173 if(d) {
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} 166}
188 167
189void IrdaApplet::showDiscovered() { 168
169void IrdaApplet::showDiscovered ( )
170{
171 static Sound snd_found ( "irdaapplet/irdaon" );
172 static Sound snd_lost ( "irdaapplet/irdaoff" );
173
190 QFile discovery("/proc/net/irda/discovery"); 174 QFile discovery("/proc/net/irda/discovery");
191 175
192 if (discovery.open(IO_ReadOnly) ) { 176 if (discovery.open(IO_ReadOnly) ) {
193 int qcopsend = FALSE; 177 bool qcopsend = false;
194 178
195 QString discoveredDevice; 179 QString discoveredDevice;
196 QString deviceAddr; 180 QString deviceAddr;
197 QStringList list; 181
198 // since it is /proc we _must_ use QTextStream 182 // since it is /proc we _must_ use QTextStream
199 QTextStream stream ( &discovery); 183 QStringList list = QStringList::split ( "\n", QTextStream ( &discovery ). read ( ));
200 QString streamIn; 184
201 streamIn = stream.read(); 185 QMap <QString, QString>::Iterator it;
202 list = QStringList::split("\n", streamIn); 186
203 187 for ( it = m_devices. begin ( ); it != m_devices. end ( ); ++it )
204 QDictIterator<QString> it( devicesAvailable ); 188 it. data ( ). prepend ( "+++" );
205 while ( it.current() ) { 189
206 devicesAvailable.replace( it.currentKey(), new QString("+++" + *devicesAvailable[it.currentKey()]) ); 190 for ( QStringList::Iterator lit = list. begin ( ); lit != list. end ( ); ++lit ) {
207 //qDebug("IrdaMon: " + it.currentKey()); 191 const QString &line = *lit;
208 //qDebug(" =" + *devicesAvailable[it.currentKey()] );
209 ++it;
210 }
211 192
212 for(QStringList::Iterator line=list.begin(); line!=list.end(); line++) { 193 if ( line. startsWith ( "nickname:" )) {
213 // qDebug( (*line) ); 194 discoveredDevice = line. mid ( line. find ( ':' ) + 2, line. find ( ',' ) - line. find ( ':' ) - 2 );
214 if( (*line).startsWith("nickname:") ){ 195 deviceAddr = line. mid ( line. find ( "daddr:" ) + 9, 8 );
215 discoveredDevice = (*line).mid(((*line).find(':'))+2,(*line).find(',')-(*line).find(':')-2);
216 deviceAddr = (*line).mid( (*line).find( "daddr:" )+9, 8 );
217 196
218 // qDebug(discoveredDevice + "(" + deviceAddr + ")"); 197 // qDebug(discoveredDevice + "(" + deviceAddr + ")");
219 198
220 if( ! devicesAvailable.find(deviceAddr) ) { 199 if ( !m_devices. contains ( deviceAddr )) {
221 popup( tr("Found:") + " " + discoveredDevice ); 200 popup( tr("Found:") + " " + discoveredDevice );
222 QSound::play(Resource::findSound("irdaapplet/irdaon")); 201 snd_found. play ( );
223 qcopsend = TRUE; 202 qcopsend = true;
224 } 203 }
225 devicesAvailable.replace( deviceAddr, new QString(discoveredDevice) ); 204 m_devices. replace ( deviceAddr, discoveredDevice );
226 // qDebug("IrdaMon: " + deviceAddr + "=" + *devicesAvailable[deviceAddr] );
227 } 205 }
228 } 206 }
229 207
230 it.toFirst(); 208 for ( it = m_devices. begin ( ); it != m_devices. end ( ); ) {
231 while ( it.current() ) {
232 // qDebug("IrdaMon: delete " + it.currentKey() + "=" + *devicesAvailable[it.currentKey()] + "?"); 209 // qDebug("IrdaMon: delete " + it.currentKey() + "=" + *devicesAvailable[it.currentKey()] + "?");
233 if ( (*it.current()).left(3) == "+++" ) { 210
234 popup( tr("Lost:") + " " + (*devicesAvailable[it.currentKey()]).mid(3) ); 211 if ( it. data ( ). left ( 3 ) == "+++" ) {
235 QSound::play(Resource::findSound("irdaapplet/irdaoff")); 212 popup ( tr( "Lost:" ) + " " + it. data ( ). mid ( 3 ));
236 devicesAvailable.remove( it.currentKey() ); 213 snd_lost. play ( );
237 // qDebug("IrdaMon: delete " + it.currentKey() + "!"); 214
238 qcopsend = TRUE; 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;
239 } 221 }
240 ++it; 222 else
223 it++;
241 } 224 }
242 /* XXX if( qcopsend ) { 225 // XXX if( qcopsend ) {
243 QCopEnvelope e("QPE/Network", "irdaSend(bool)" ); 226 QCopEnvelope e("QPE/Network", "irdaSend(bool)" );
244 e << (devicesAvailable.count() > 0) ; 227 e << ( m_devices. count ( ) > 0 );
245 } */ 228 // }
246 } 229 }
247} 230}
248 231
249void IrdaApplet::mousePressEvent( QMouseEvent *) { 232void IrdaApplet::mousePressEvent ( QMouseEvent * )
250 QPopupMenu *menu = new QPopupMenu(); 233{
234 QPopupMenu *menu = new QPopupMenu ( this );
251 QString cmd; 235 QString cmd;
252 int ret=0;
253 236
254 /* Refresh active state */ 237 /* Refresh active state */
255 timerEvent(NULL); 238 timerEvent ( 0 );
256 239
257 //menu->insertItem( tr("More..."), 4 ); 240 //menu->insertItem( tr("More..."), 4 );
258 241
259 if (irdaactive && devicesAvailable.count() > 0) { 242 if ( m_irda_active && !m_devices. isEmpty ( )) {
260 menu->insertItem( tr("Discovered Device:"), 9); 243 menu->insertItem( tr("Discovered Device:"), 9);
261 QDictIterator<QString> it( devicesAvailable );
262 while ( it.current() ) {
263 menu->insertItem( *devicesAvailable[it.currentKey()]);
264 ++it;
265 }
266 menu->insertSeparator();
267 }
268 244
269 if (irdaactive) { 245 for ( QMap<QString, QString>::Iterator it = m_devices. begin ( ); it != m_devices. end ( ); ++it )
270 menu->insertItem( tr("Disable IrDA"), 0 ); 246 menu-> insertItem ( *it );
271 } else {
272 menu->insertItem( tr("Enable IrDA"), 1 );
273 }
274 247
275 if (irdaactive) { 248 menu-> insertSeparator ( );
276 if (irdaDiscoveryActive) {
277 menu->insertItem( tr("Disable Discovery"), 2 );
278 } else {
279 menu->insertItem( tr("Enable Discovery"), 3 );
280 } 249 }
281 250
282 if( receiveActive ){ 251 menu-> insertItem ( m_irda_active ? tr( "Disable IrDA" ) : tr( "Enable IrDA" ), 0 );
283 menu->insertItem( tr("Disable Receive"), 4 ); 252
284 } else { 253 if ( m_irda_active ) {
285 menu->insertItem( tr("Enable Receive"), 5 ); 254 menu-> insertItem ( m_irda_discovery_active ? tr( "Disable Discovery" ) : tr( "Enable Discovery" ), 1 );
286 } 255 menu-> insertItem ( m_receive_active ? tr( "Disable Receive" ) : tr( "Enable Receive" ), 2 );
287 } 256 }
288 257
289 QPoint p = mapToGlobal ( QPoint ( 0, 0 )); 258 QPoint p = mapToGlobal ( QPoint ( 0, 0 ));
290 QSize s = menu-> sizeHint ( ); 259 QSize s = menu-> sizeHint ( );
291 ret = menu->exec( QPoint (
292 p. x ( ) + ( width ( ) / 2 ) - ( s. width ( ) / 2 ),
293 p. y ( ) - s. height ( ) ), 0);
294 260
295 // qDebug("ret was %d\n", ret); 261 p = QPoint ( p. x ( ) + ( width ( ) / 2 ) - ( s. width ( ) / 2 ), p. y ( ) - s. height ( ));
296 262
297 switch(ret) { 263 switch ( menu-> exec ( p )) {
298 case 0: 264 case 0:
299 setIrdaStatus(0); 265 setIrdaStatus ( !m_irda_active );
300 timerEvent(NULL); 266 timerEvent ( 0 );
301 break; 267 break;
302 case 1: 268 case 1:
303 setIrdaStatus(1); 269 setIrdaDiscoveryStatus ( !m_irda_discovery_active );
304 timerEvent(NULL); 270 timerEvent ( 0 );
305 break; 271 break;
306 case 2: 272 case 2:
307 setIrdaDiscoveryStatus(0); 273 setIrdaReceiveStatus ( !m_receive_active );
308 timerEvent(NULL); 274 timerEvent( 0 );
309 break; 275 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 } 276 }
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 277
278 delete menu;
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;
284 bool olddiscovery = m_irda_discovery_active;
331 bool receiveUpdate = false; 285 bool receiveUpdate = false;
332 286
333 if (receiveStateChanged) { 287 if ( m_receive_state_changed ) {
334 receiveUpdate = true; 288 receiveUpdate = true;
335 receiveStateChanged = false; 289 m_receive_state_changed = false;
336 } 290 }
337 291
338 irdaactive = checkIrdaStatus(); 292 m_irda_active = checkIrdaStatus ( );
339 irdaDiscoveryActive = checkIrdaDiscoveryStatus(); 293 m_irda_discovery_active = checkIrdaDiscoveryStatus ( );
340
341 294
342 if (irdaDiscoveryActive) { 295 if ( m_irda_discovery_active )
343 showDiscovered(); 296 showDiscovered();
344 }
345
346 if ((irdaactive != oldactive) || (irdaDiscoveryActive != olddiscovery) || receiveUpdate ) {
347 paintEvent(NULL);
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 * )
303{
353 QPainter p(this); 304 QPainter p(this);
354 // qDebug("paint irda pixmap");
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) {
358 p.drawPixmap( 0, 0, irdaOnPixmap );
359 } else {
360 p.drawPixmap( 0, 0, irdaOffPixmap );
361 }
362 307
363 if (irdaDiscoveryActive > 0) { 308 if ( m_irda_discovery_active )
364 p.drawPixmap( 0, 0, irdaDiscoveryOnPixmap ); 309 p. drawPixmap( 0, 1, m_irdaDiscoveryOnPixmap );
365 } 310
366 if (receiveActive) { 311 if ( m_receive_active )
367 p.drawPixmap( 0, 0, receiveActivePixmap); 312 p. drawPixmap( 0, 1, m_receiveActivePixmap );
368 }
369} 313}