summaryrefslogtreecommitdiff
path: root/library/alarmserver.cpp
Unidiff
Diffstat (limited to 'library/alarmserver.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/alarmserver.cpp5
1 files changed, 0 insertions, 5 deletions
diff --git a/library/alarmserver.cpp b/library/alarmserver.cpp
index 6f6f32d..48ab9c1 100644
--- a/library/alarmserver.cpp
+++ b/library/alarmserver.cpp
@@ -1,512 +1,507 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of the Qtopia Environment. 4** This file is part of the Qtopia Environment.
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
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#include <qdir.h> 21#include <qdir.h>
22#include <qfile.h>
23#include <qmessagebox.h>
24#include <qtextstream.h>
25 22
26 23
27#include <qpe/qpeapplication.h> 24#include <qpe/qpeapplication.h>
28#include "global.h"
29#include "resource.h"
30 25
31#include <qpe/qcopenvelope_qws.h> 26#include <qpe/qcopenvelope_qws.h>
32#include "alarmserver.h" 27#include "alarmserver.h"
33#include <qpe/timeconversion.h> 28#include <qpe/timeconversion.h>
34 29
35#include <sys/types.h> 30#include <sys/types.h>
36#include <sys/stat.h> 31#include <sys/stat.h>
37 32
38#include <stdlib.h> 33#include <stdlib.h>
39#include <unistd.h> 34#include <unistd.h>
40 35
41 36
42#undef USE_ATD // not used anymore -- we run opie-alarm on suspend/resume 37#undef USE_ATD // not used anymore -- we run opie-alarm on suspend/resume
43 38
44 39
45struct timerEventItem 40struct timerEventItem
46{ 41{
47 time_t UTCtime; 42 time_t UTCtime;
48 QCString channel, message; 43 QCString channel, message;
49 int data; 44 int data;
50 bool operator==( const timerEventItem &right ) const 45 bool operator==( const timerEventItem &right ) const
51 { 46 {
52 return ( UTCtime == right.UTCtime 47 return ( UTCtime == right.UTCtime
53 && channel == right.channel 48 && channel == right.channel
54 && message == right.message 49 && message == right.message
55 && data == right.data ); 50 && data == right.data );
56 } 51 }
57}; 52};
58 53
59class TimerReceiverObject : public QObject 54class TimerReceiverObject : public QObject
60{ 55{
61public: 56public:
62 TimerReceiverObject() 57 TimerReceiverObject()
63 { } 58 { }
64 ~TimerReceiverObject() 59 ~TimerReceiverObject()
65 { } 60 { }
66 void resetTimer(); 61 void resetTimer();
67 void setTimerEventItem(); 62 void setTimerEventItem();
68 void deleteTimer(); 63 void deleteTimer();
69protected: 64protected:
70 void timerEvent( QTimerEvent *te ); 65 void timerEvent( QTimerEvent *te );
71 66
72#ifdef USE_ATD 67#ifdef USE_ATD
73private: 68private:
74 QString atfilename; 69 QString atfilename;
75#endif 70#endif
76}; 71};
77 72
78TimerReceiverObject *timerEventReceiver = NULL; 73TimerReceiverObject *timerEventReceiver = NULL;
79QList<timerEventItem> timerEventList; 74QList<timerEventItem> timerEventList;
80timerEventItem *nearestTimerEvent = NULL; 75timerEventItem *nearestTimerEvent = NULL;
81 76
82 77
83// set the timer to go off on the next event in the list 78// set the timer to go off on the next event in the list
84void setNearestTimerEvent() 79void setNearestTimerEvent()
85{ 80{
86 nearestTimerEvent = NULL; 81 nearestTimerEvent = NULL;
87 QListIterator<timerEventItem> it( timerEventList ); 82 QListIterator<timerEventItem> it( timerEventList );
88 if ( *it ) 83 if ( *it )
89 nearestTimerEvent = *it; 84 nearestTimerEvent = *it;
90 for ( ; *it; ++it ) 85 for ( ; *it; ++it )
91 if ( (*it)->UTCtime < nearestTimerEvent->UTCtime ) 86 if ( (*it)->UTCtime < nearestTimerEvent->UTCtime )
92 nearestTimerEvent = *it; 87 nearestTimerEvent = *it;
93 if (nearestTimerEvent) 88 if (nearestTimerEvent)
94 timerEventReceiver->resetTimer(); 89 timerEventReceiver->resetTimer();
95 else 90 else
96 timerEventReceiver->deleteTimer(); 91 timerEventReceiver->deleteTimer();
97} 92}
98 93
99 94
100//store current state to file 95//store current state to file
101//Simple implementation. Should run on a timer. 96//Simple implementation. Should run on a timer.
102 97
103static void saveState() 98static void saveState()
104{ 99{
105 QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" ); 100 QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" );
106 if ( timerEventList.isEmpty() ) { 101 if ( timerEventList.isEmpty() ) {
107 unlink( savefilename ); 102 unlink( savefilename );
108 return ; 103 return ;
109 } 104 }
110 105
111 QFile savefile(savefilename + ".new"); 106 QFile savefile(savefilename + ".new");
112 if ( savefile.open(IO_WriteOnly) ) { 107 if ( savefile.open(IO_WriteOnly) ) {
113 QDataStream ds( &savefile ); 108 QDataStream ds( &savefile );
114 109
115 //save 110 //save
116 111
117 QListIterator<timerEventItem> it( timerEventList ); 112 QListIterator<timerEventItem> it( timerEventList );
118 for ( ; *it; ++it ) { 113 for ( ; *it; ++it ) {
119 ds << it.current()->UTCtime; 114 ds << it.current()->UTCtime;
120 ds << it.current()->channel; 115 ds << it.current()->channel;
121 ds << it.current()->message; 116 ds << it.current()->message;
122 ds << it.current()->data; 117 ds << it.current()->data;
123 } 118 }
124 119
125 120
126 savefile.close(); 121 savefile.close();
127 unlink( savefilename ); 122 unlink( savefilename );
128 QDir d; 123 QDir d;
129 d.rename(savefilename + ".new", savefilename); 124 d.rename(savefilename + ".new", savefilename);
130 125
131 } 126 }
132} 127}
133 128
134/*! 129/*!
135 Sets up the alarm server. Restoring to previous state (session management). 130 Sets up the alarm server. Restoring to previous state (session management).
136 */ 131 */
137void AlarmServer::initialize() 132void AlarmServer::initialize()
138{ 133{
139 //read autosave file and put events in timerEventList 134 //read autosave file and put events in timerEventList
140 135
141 QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" ); 136 QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" );
142 137
143 QFile savefile(savefilename); 138 QFile savefile(savefilename);
144 if ( savefile.open(IO_ReadOnly) ) { 139 if ( savefile.open(IO_ReadOnly) ) {
145 QDataStream ds( &savefile ); 140 QDataStream ds( &savefile );
146 while ( !ds.atEnd() ) { 141 while ( !ds.atEnd() ) {
147 timerEventItem *newTimerEventItem = new timerEventItem; 142 timerEventItem *newTimerEventItem = new timerEventItem;
148 ds >> newTimerEventItem->UTCtime; 143 ds >> newTimerEventItem->UTCtime;
149 ds >> newTimerEventItem->channel; 144 ds >> newTimerEventItem->channel;
150 ds >> newTimerEventItem->message; 145 ds >> newTimerEventItem->message;
151 ds >> newTimerEventItem->data; 146 ds >> newTimerEventItem->data;
152 timerEventList.append( newTimerEventItem ); 147 timerEventList.append( newTimerEventItem );
153 } 148 }
154 savefile.close(); 149 savefile.close();
155 if (!timerEventReceiver) 150 if (!timerEventReceiver)
156 timerEventReceiver = new TimerReceiverObject; 151 timerEventReceiver = new TimerReceiverObject;
157 setNearestTimerEvent(); 152 setNearestTimerEvent();
158 } 153 }
159} 154}
160 155
161 156
162#ifdef USE_ATD 157#ifdef USE_ATD
163 158
164static const char* atdir = "/var/spool/at/"; 159static const char* atdir = "/var/spool/at/";
165 160
166static bool triggerAtd( bool writeHWClock = FALSE ) 161static bool triggerAtd( bool writeHWClock = FALSE )
167{ 162{
168 QFile trigger(QString(atdir) + "trigger"); 163 QFile trigger(QString(atdir) + "trigger");
169 if ( trigger.open(IO_WriteOnly | IO_Raw) ) { 164 if ( trigger.open(IO_WriteOnly | IO_Raw) ) {
170 if ( trigger.writeBlock("\n", 2) != 2 ) { 165 if ( trigger.writeBlock("\n", 2) != 2 ) {
171 QMessageBox::critical( 0, QObject::tr( "Out of Space" ), 166 QMessageBox::critical( 0, QObject::tr( "Out of Space" ),
172 QObject::tr( "Unable to schedule alarm.\nFree some memory and try again." ) ); 167 QObject::tr( "Unable to schedule alarm.\nFree some memory and try again." ) );
173 trigger.close(); 168 trigger.close();
174 QFile::remove 169 QFile::remove
175 ( trigger.name() ); 170 ( trigger.name() );
176 return FALSE; 171 return FALSE;
177 } 172 }
178 return TRUE; 173 return TRUE;
179 } 174 }
180 return FALSE; 175 return FALSE;
181} 176}
182 177
183#else 178#else
184 179
185static bool writeResumeAt ( time_t wakeup ) 180static bool writeResumeAt ( time_t wakeup )
186{ 181{
187 FILE *fp = ::fopen ( "/var/run/resumeat", "w" ); 182 FILE *fp = ::fopen ( "/var/run/resumeat", "w" );
188 183
189 if ( fp ) { 184 if ( fp ) {
190 ::fprintf ( fp, "%d\n", (int) wakeup ); 185 ::fprintf ( fp, "%d\n", (int) wakeup );
191 ::fclose ( fp ); 186 ::fclose ( fp );
192 } 187 }
193 else 188 else
194 qWarning ( "Failed to write wakeup time to /var/run/resumeat" ); 189 qWarning ( "Failed to write wakeup time to /var/run/resumeat" );
195 190
196 return ( fp ); 191 return ( fp );
197} 192}
198 193
199#endif 194#endif
200 195
201void TimerReceiverObject::deleteTimer() 196void TimerReceiverObject::deleteTimer()
202{ 197{
203#ifdef USE_ATD 198#ifdef USE_ATD
204 if ( !atfilename.isEmpty() ) { 199 if ( !atfilename.isEmpty() ) {
205 unlink( atfilename ); 200 unlink( atfilename );
206 atfilename = QString::null; 201 atfilename = QString::null;
207 triggerAtd( FALSE ); 202 triggerAtd( FALSE );
208 } 203 }
209#else 204#else
210 writeResumeAt ( 0 ); 205 writeResumeAt ( 0 );
211#endif 206#endif
212} 207}
213 208
214void TimerReceiverObject::resetTimer() 209void TimerReceiverObject::resetTimer()
215{ 210{
216 const int maxsecs = 2147000; 211 const int maxsecs = 2147000;
217 QDateTime nearest = TimeConversion::fromUTC(nearestTimerEvent->UTCtime); 212 QDateTime nearest = TimeConversion::fromUTC(nearestTimerEvent->UTCtime);
218 QDateTime now = QDateTime::currentDateTime(); 213 QDateTime now = QDateTime::currentDateTime();
219 if ( nearest < now ) 214 if ( nearest < now )
220 nearest = now; 215 nearest = now;
221 int secs = TimeConversion::secsTo( now, nearest ); 216 int secs = TimeConversion::secsTo( now, nearest );
222 if ( secs > maxsecs ) { 217 if ( secs > maxsecs ) {
223 // too far for millisecond timing 218 // too far for millisecond timing
224 secs = maxsecs; 219 secs = maxsecs;
225 } 220 }
226 221
227 // System timer (needed so that we wake from deep sleep), 222 // System timer (needed so that we wake from deep sleep),
228 // from the Epoch in seconds. 223 // from the Epoch in seconds.
229 // 224 //
230 int at_secs = TimeConversion::toUTC(nearest); 225 int at_secs = TimeConversion::toUTC(nearest);
231 // qDebug("reset timer to %d seconds from Epoch",at_secs); 226 // qDebug("reset timer to %d seconds from Epoch",at_secs);
232 227
233#ifdef USE_ATD 228#ifdef USE_ATD
234 229
235 QString fn = atdir + QString::number(at_secs) + "." 230 QString fn = atdir + QString::number(at_secs) + "."
236 + QString::number(getpid()); 231 + QString::number(getpid());
237 if ( fn != atfilename ) { 232 if ( fn != atfilename ) {
238 QFile atfile(fn + ".new"); 233 QFile atfile(fn + ".new");
239 if ( atfile.open(IO_WriteOnly | IO_Raw) ) { 234 if ( atfile.open(IO_WriteOnly | IO_Raw) ) {
240 int total_written; 235 int total_written;
241 236
242 // just wake up and delete the at file 237 // just wake up and delete the at file
243 QString cmd = "#!/bin/sh\nrm " + fn; 238 QString cmd = "#!/bin/sh\nrm " + fn;
244 total_written = atfile.writeBlock(cmd.latin1(), cmd.length()); 239 total_written = atfile.writeBlock(cmd.latin1(), cmd.length());
245 if ( total_written != int(cmd.length()) ) { 240 if ( total_written != int(cmd.length()) ) {
246 QMessageBox::critical( 0, tr("Out of Space"), 241 QMessageBox::critical( 0, tr("Out of Space"),
247 tr("Unable to schedule alarm.\n" 242 tr("Unable to schedule alarm.\n"
248 "Please free up space and try again") ); 243 "Please free up space and try again") );
249 atfile.close(); 244 atfile.close();
250 QFile::remove 245 QFile::remove
251 ( atfile.name() ); 246 ( atfile.name() );
252 return ; 247 return ;
253 } 248 }
254 atfile.close(); 249 atfile.close();
255 unlink( atfilename ); 250 unlink( atfilename );
256 QDir d; 251 QDir d;
257 d.rename(fn + ".new", fn); 252 d.rename(fn + ".new", fn);
258 chmod(fn.latin1(), 0755); 253 chmod(fn.latin1(), 0755);
259 atfilename = fn; 254 atfilename = fn;
260 triggerAtd( FALSE ); 255 triggerAtd( FALSE );
261 } 256 }
262 else { 257 else {
263 qWarning("Cannot open atd file %s", fn.latin1()); 258 qWarning("Cannot open atd file %s", fn.latin1());
264 } 259 }
265 } 260 }
266#else 261#else
267 writeResumeAt ( at_secs ); 262 writeResumeAt ( at_secs );
268 263
269#endif 264#endif
270 265
271 // Qt timers (does the actual alarm) 266 // Qt timers (does the actual alarm)
272 // from now in milliseconds 267 // from now in milliseconds
273 // 268 //
274 qDebug("AlarmServer waiting %d seconds", secs); 269 qDebug("AlarmServer waiting %d seconds", secs);
275 startTimer( 1000 * secs + 500 ); 270 startTimer( 1000 * secs + 500 );
276} 271}
277 272
278void TimerReceiverObject::timerEvent( QTimerEvent * ) 273void TimerReceiverObject::timerEvent( QTimerEvent * )
279{ 274{
280 bool needSave = FALSE; 275 bool needSave = FALSE;
281 killTimers(); 276 killTimers();
282 if (nearestTimerEvent) { 277 if (nearestTimerEvent) {
283 if ( nearestTimerEvent->UTCtime 278 if ( nearestTimerEvent->UTCtime
284 <= TimeConversion::toUTC(QDateTime::currentDateTime()) ) { 279 <= TimeConversion::toUTC(QDateTime::currentDateTime()) ) {
285#ifndef QT_NO_COP 280#ifndef QT_NO_COP
286 QCopEnvelope e( nearestTimerEvent->channel, 281 QCopEnvelope e( nearestTimerEvent->channel,
287 nearestTimerEvent->message ); 282 nearestTimerEvent->message );
288 e << TimeConversion::fromUTC( nearestTimerEvent->UTCtime ) 283 e << TimeConversion::fromUTC( nearestTimerEvent->UTCtime )
289 << nearestTimerEvent->data; 284 << nearestTimerEvent->data;
290#endif 285#endif
291 286
292 timerEventList.remove( nearestTimerEvent ); 287 timerEventList.remove( nearestTimerEvent );
293 needSave = TRUE; 288 needSave = TRUE;
294 } 289 }
295 setNearestTimerEvent(); 290 setNearestTimerEvent();
296 } 291 }
297 else { 292 else {
298 resetTimer(); 293 resetTimer();
299 } 294 }
300 if ( needSave ) 295 if ( needSave )
301 saveState(); 296 saveState();
302} 297}
303 298
304/*! 299/*!
305 \class AlarmServer alarmserver.h 300 \class AlarmServer alarmserver.h
306 \brief The AlarmServer class allows alarms to be scheduled and unscheduled. 301 \brief The AlarmServer class allows alarms to be scheduled and unscheduled.
307 302
308 Applications can schedule alarms with addAlarm() and can 303 Applications can schedule alarms with addAlarm() and can
309 unschedule alarms with deleteAlarm(). When the time for an alarm 304 unschedule alarms with deleteAlarm(). When the time for an alarm
310 to go off is reached the specified \link qcop.html QCop\endlink 305 to go off is reached the specified \link qcop.html QCop\endlink
311 message is sent on the specified channel (optionally with 306 message is sent on the specified channel (optionally with
312 additional data). 307 additional data).
313 308
314 Scheduling an alarm using this class is important (rather just using 309 Scheduling an alarm using this class is important (rather just using
315 a QTimer) since the machine may be asleep and needs to get woken up using 310 a QTimer) since the machine may be asleep and needs to get woken up using
316 the Linux kernel which implements this at the kernel level to minimize 311 the Linux kernel which implements this at the kernel level to minimize
317 battery usage while asleep. 312 battery usage while asleep.
318 313
319 A small example on how to use AlarmServer. 314 A small example on how to use AlarmServer.
320 315
321 First we need to connect a slot the AppMessage QCOP call. appMessage 316 First we need to connect a slot the AppMessage QCOP call. appMessage
322 will be emitted if QPE/Application/appname gets called. 317 will be emitted if QPE/Application/appname gets called.
323 318
324 \code 319 \code
325 TestApp::TestApp(QWidget *parent, const char* name, WFlags fl ) 320 TestApp::TestApp(QWidget *parent, const char* name, WFlags fl )
326 : QMainWindow(parent,name,fl){ 321 : QMainWindow(parent,name,fl){
327 connect(qApp,SIGNAL(appMessage(const QCString&,const QByteArray&)), 322 connect(qApp,SIGNAL(appMessage(const QCString&,const QByteArray&)),
328 this,SLOT(slotAppMessage(const QCString&,const QByteArray&))); 323 this,SLOT(slotAppMessage(const QCString&,const QByteArray&)));
329 } 324 }
330 \endcode 325 \endcode
331 326
332 To add / delete an alarm, you can use the static method AlarmServer::addAlarm and 327 To add / delete an alarm, you can use the static method AlarmServer::addAlarm and
333 AlarmServer::deleteAlarm. Note that an old (expired) alarm will automatically be deleted 328 AlarmServer::deleteAlarm. Note that an old (expired) alarm will automatically be deleted
334 from the alarmserver list, but a change in timing will have the effect, that both 329 from the alarmserver list, but a change in timing will have the effect, that both
335 alarms will be emitted. So if you change an Alarm be sure to delete the old one! 330 alarms will be emitted. So if you change an Alarm be sure to delete the old one!
336 @see addAlarm 331 @see addAlarm
337 332
338 \code 333 \code
339 QDateTime oldDt = oldAlarmDateTime(); 334 QDateTime oldDt = oldAlarmDateTime();
340 QPEApplication::execDialog(ourDlg); 335 QPEApplication::execDialog(ourDlg);
341 QDateTime newDt = ourDlg->dateTime(); 336 QDateTime newDt = ourDlg->dateTime();
342 if(newDt == oldDt ) return; 337 if(newDt == oldDt ) return;
343 @slash* code is missing for unsetting an alarm *@slash 338 @slash* code is missing for unsetting an alarm *@slash
344 339
345 AlarmServer::deleteAlarm(oldDt,"QPE/Application/appname","checkAlarm(QDateTime,int)",0); 340 AlarmServer::deleteAlarm(oldDt,"QPE/Application/appname","checkAlarm(QDateTime,int)",0);
346 AlarmServer::addAlarm( newDt,"QPE/AlarmServer/appname","checkAlarm(QDateTime,int)",0); 341 AlarmServer::addAlarm( newDt,"QPE/AlarmServer/appname","checkAlarm(QDateTime,int)",0);
347 342
348 \endcode 343 \endcode
349 344
350 Now once the Alarm is emitted you need to check the appMessage and then do what you want. 345 Now once the Alarm is emitted you need to check the appMessage and then do what you want.
351 \code 346 \code
352 void TestApp::slotAppMessage(const QCString& str, const QByteArray& ar ){ 347 void TestApp::slotAppMessage(const QCString& str, const QByteArray& ar ){
353 QDataStream stream(ar,IO_ReadOnly); 348 QDataStream stream(ar,IO_ReadOnly);
354 if(str == "checkAlarm(QDateTime,int)" ){ 349 if(str == "checkAlarm(QDateTime,int)" ){
355 QDateTime dt; 350 QDateTime dt;
356 int a; 351 int a;
357 stream >> dt >> a; 352 stream >> dt >> a;
358 // fire up alarm 353 // fire up alarm
359 } 354 }
360 } 355 }
361 \endcode 356 \endcode
362 357
363 \ingroup qtopiaemb 358 \ingroup qtopiaemb
364 \sa QCopEnvelope 359 \sa QCopEnvelope
365 @see QPEApplication::appMessage(const QCString&,const QByteArray&) 360 @see QPEApplication::appMessage(const QCString&,const QByteArray&)
366 @see OPimMainWindow 361 @see OPimMainWindow
367 @see ODevice::alarmSound() 362 @see ODevice::alarmSound()
368 @see Sound::soundAlarm() 363 @see Sound::soundAlarm()
369*/ 364*/
370 365
371/*! 366/*!
372 Schedules an alarm to go off at (or soon after) time \a when. When 367 Schedules an alarm to go off at (or soon after) time \a when. When
373 the alarm goes off, the \link qcop.html QCop\endlink \a message will 368 the alarm goes off, the \link qcop.html QCop\endlink \a message will
374 be sent to \a channel, with \a data as a parameter. 369 be sent to \a channel, with \a data as a parameter.
375 370
376 If this function is called with exactly the same data as a previous 371 If this function is called with exactly the same data as a previous
377 call the subsequent call is ignored, so there is only ever one alarm 372 call the subsequent call is ignored, so there is only ever one alarm
378 with a given set of parameters. 373 with a given set of parameters.
379 374
380 Once an alarm is emitted. The \a channel with a \a message will be emitted 375 Once an alarm is emitted. The \a channel with a \a message will be emitted
381 and data will be send. 376 and data will be send.
382 The QDateTime and int are the two parameters included in the QCOP message. 377 The QDateTime and int are the two parameters included in the QCOP message.
383 You can specify channel, message and the integer parameter. QDateTime will be 378 You can specify channel, message and the integer parameter. QDateTime will be
384 the datetime of the QCop call. 379 the datetime of the QCop call.
385 380
386 @param when The QDateTime of the alarm 381 @param when The QDateTime of the alarm
387 @param channel The channel which gets called once the alarm is emitted 382 @param channel The channel which gets called once the alarm is emitted
388 @param message The message to be send to the channel 383 @param message The message to be send to the channel
389 @param data Additional data as integer 384 @param data Additional data as integer
390 385
391 @see QCopChannel 386 @see QCopChannel
392 \sa deleteAlarm() 387 \sa deleteAlarm()
393*/ 388*/
394void AlarmServer::addAlarm ( QDateTime when, const QCString& channel, 389void AlarmServer::addAlarm ( QDateTime when, const QCString& channel,
395 const QCString& message, int data) 390 const QCString& message, int data)
396{ 391{
397 if ( qApp->type() == QApplication::GuiServer ) { 392 if ( qApp->type() == QApplication::GuiServer ) {
398 bool needSave = FALSE; 393 bool needSave = FALSE;
399 // Here we are the server so either it has been directly called from 394 // Here we are the server so either it has been directly called from
400 // within the server or it has been sent to us from a client via QCop 395 // within the server or it has been sent to us from a client via QCop
401 if (!timerEventReceiver) 396 if (!timerEventReceiver)
402 timerEventReceiver = new TimerReceiverObject; 397 timerEventReceiver = new TimerReceiverObject;
403 398
404 timerEventItem *newTimerEventItem = new timerEventItem; 399 timerEventItem *newTimerEventItem = new timerEventItem;
405 newTimerEventItem->UTCtime = TimeConversion::toUTC( when ); 400 newTimerEventItem->UTCtime = TimeConversion::toUTC( when );
406 newTimerEventItem->channel = channel; 401 newTimerEventItem->channel = channel;
407 newTimerEventItem->message = message; 402 newTimerEventItem->message = message;
408 newTimerEventItem->data = data; 403 newTimerEventItem->data = data;
409 // explore the case of already having the event in here... 404 // explore the case of already having the event in here...
410 QListIterator<timerEventItem> it( timerEventList ); 405 QListIterator<timerEventItem> it( timerEventList );
411 for ( ; *it; ++it ) 406 for ( ; *it; ++it )
412 if ( *(*it) == *newTimerEventItem ) 407 if ( *(*it) == *newTimerEventItem )
413 return ; 408 return ;
414 // if we made it here, it is okay to add the item... 409 // if we made it here, it is okay to add the item...
415 timerEventList.append( newTimerEventItem ); 410 timerEventList.append( newTimerEventItem );
416 needSave = TRUE; 411 needSave = TRUE;
417 // quicker than using setNearestTimerEvent() 412 // quicker than using setNearestTimerEvent()
418 if ( nearestTimerEvent ) { 413 if ( nearestTimerEvent ) {
419 if (newTimerEventItem->UTCtime < nearestTimerEvent->UTCtime) { 414 if (newTimerEventItem->UTCtime < nearestTimerEvent->UTCtime) {
420 nearestTimerEvent = newTimerEventItem; 415 nearestTimerEvent = newTimerEventItem;
421 timerEventReceiver->killTimers(); 416 timerEventReceiver->killTimers();
422 timerEventReceiver->resetTimer(); 417 timerEventReceiver->resetTimer();
423 } 418 }
424 } 419 }
425 else { 420 else {
426 nearestTimerEvent = newTimerEventItem; 421 nearestTimerEvent = newTimerEventItem;
427 timerEventReceiver->resetTimer(); 422 timerEventReceiver->resetTimer();
428 } 423 }
429 if ( needSave ) 424 if ( needSave )
430 saveState(); 425 saveState();
431 } 426 }
432 else { 427 else {
433#ifndef QT_NO_COP 428#ifndef QT_NO_COP
434 QCopEnvelope e( "QPE/System", "addAlarm(QDateTime,QCString,QCString,int)" ); 429 QCopEnvelope e( "QPE/System", "addAlarm(QDateTime,QCString,QCString,int)" );
435 e << when << channel << message << data; 430 e << when << channel << message << data;
436#endif 431#endif
437 432
438 } 433 }
439} 434}
440 435
441/*! 436/*!
442 Deletes previously scheduled alarms which match \a when, \a channel, 437 Deletes previously scheduled alarms which match \a when, \a channel,
443 \a message, and \a data. 438 \a message, and \a data.
444 439
445 Passing null values for \a when, \a channel, or for the \link 440 Passing null values for \a when, \a channel, or for the \link
446 qcop.html QCop\endlink \a message, acts as a wildcard meaning "any". 441 qcop.html QCop\endlink \a message, acts as a wildcard meaning "any".
447 Similarly, passing -1 for \a data indicates "any". 442 Similarly, passing -1 for \a data indicates "any".
448 443
449 If there is no matching alarm, nothing happens. 444 If there is no matching alarm, nothing happens.
450 445
451 \sa addAlarm() 446 \sa addAlarm()
452 447
453*/ 448*/
454void AlarmServer::deleteAlarm (QDateTime when, const QCString& channel, const QCString& message, int data) 449void AlarmServer::deleteAlarm (QDateTime when, const QCString& channel, const QCString& message, int data)
455{ 450{
456 if ( qApp->type() == QApplication::GuiServer) { 451 if ( qApp->type() == QApplication::GuiServer) {
457 bool needSave = FALSE; 452 bool needSave = FALSE;
458 if ( timerEventReceiver != NULL ) { 453 if ( timerEventReceiver != NULL ) {
459 timerEventReceiver->killTimers(); 454 timerEventReceiver->killTimers();
460 455
461 // iterate over the list of events 456 // iterate over the list of events
462 QListIterator<timerEventItem> it( timerEventList ); 457 QListIterator<timerEventItem> it( timerEventList );
463 time_t deleteTime = TimeConversion::toUTC( when ); 458 time_t deleteTime = TimeConversion::toUTC( when );
464 for ( ; *it; ++it ) { 459 for ( ; *it; ++it ) {
465 // if its a match, delete it 460 // if its a match, delete it
466 if ( ( (*it)->UTCtime == deleteTime || when.isNull() ) 461 if ( ( (*it)->UTCtime == deleteTime || when.isNull() )
467 && ( channel.isNull() || (*it)->channel == channel ) 462 && ( channel.isNull() || (*it)->channel == channel )
468 && ( message.isNull() || (*it)->message == message ) 463 && ( message.isNull() || (*it)->message == message )
469 && ( data == -1 || (*it)->data == data ) ) { 464 && ( data == -1 || (*it)->data == data ) ) {
470 // if it's first, then we need to update the timer 465 // if it's first, then we need to update the timer
471 if ( (*it) == nearestTimerEvent ) { 466 if ( (*it) == nearestTimerEvent ) {
472 timerEventList.remove(*it); 467 timerEventList.remove(*it);
473 setNearestTimerEvent(); 468 setNearestTimerEvent();
474 } 469 }
475 else { 470 else {
476 timerEventList.remove(*it); 471 timerEventList.remove(*it);
477 } 472 }
478 needSave = TRUE; 473 needSave = TRUE;
479 } 474 }
480 } 475 }
481 if ( nearestTimerEvent ) 476 if ( nearestTimerEvent )
482 timerEventReceiver->resetTimer(); 477 timerEventReceiver->resetTimer();
483 } 478 }
484 if ( needSave ) 479 if ( needSave )
485 saveState(); 480 saveState();
486 } 481 }
487 else { 482 else {
488#ifndef QT_NO_COP 483#ifndef QT_NO_COP
489 QCopEnvelope e( "QPE/System", "deleteAlarm(QDateTime,QCString,QCString,int)" ); 484 QCopEnvelope e( "QPE/System", "deleteAlarm(QDateTime,QCString,QCString,int)" );
490 e << when << channel << message << data; 485 e << when << channel << message << data;
491#endif 486#endif
492 487
493 } 488 }
494} 489}
495 490
496/*! 491/*!
497 The implementation depends on the mode of AlarmServer. If the AlarmServer 492 The implementation depends on the mode of AlarmServer. If the AlarmServer
498 uses atd the current system time will be written to the hardware clock. 493 uses atd the current system time will be written to the hardware clock.
499 If the AlarmServer relies on opie-alarm the time will be written once the 494 If the AlarmServer relies on opie-alarm the time will be written once the
500 device gets suspended. opie-alarm is used by the Zaurus, iPAQs and SIMpad 495 device gets suspended. opie-alarm is used by the Zaurus, iPAQs and SIMpad
501*/ 496*/
502void Global::writeHWClock() 497void Global::writeHWClock()
503{ 498{
504#ifdef USE_ATD 499#ifdef USE_ATD
505 if ( !triggerAtd( TRUE ) ) { 500 if ( !triggerAtd( TRUE ) ) {
506 // atd not running? set it ourselves 501 // atd not running? set it ourselves
507 system("/sbin/hwclock --systohc"); // ##### UTC? 502 system("/sbin/hwclock --systohc"); // ##### UTC?
508 } 503 }
509#else 504#else
510 // hwclock is written on suspend 505 // hwclock is written on suspend
511#endif 506#endif
512} 507}