summaryrefslogtreecommitdiff
path: root/library/alarmserver.cpp
authorzecke <zecke>2002-09-10 12:09:49 (UTC)
committer zecke <zecke>2002-09-10 12:09:49 (UTC)
commit6b77a1cdb9536b1c135eb86d53a6b2c22c19b0a4 (patch) (unidiff)
tree6ebc93c6432f4ed9d00ef1448b6a047ef522a79a /library/alarmserver.cpp
parentd10cddb3c9ce75bc90b14add14bc133737fe35aa (diff)
downloadopie-6b77a1cdb9536b1c135eb86d53a6b2c22c19b0a4.zip
opie-6b77a1cdb9536b1c135eb86d53a6b2c22c19b0a4.tar.gz
opie-6b77a1cdb9536b1c135eb86d53a6b2c22c19b0a4.tar.bz2
Qtopia1-6 merge
still to test bic changes to be resolved more changes to be made?
Diffstat (limited to 'library/alarmserver.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/alarmserver.cpp53
1 files changed, 40 insertions, 13 deletions
diff --git a/library/alarmserver.cpp b/library/alarmserver.cpp
index a1a7142..1ee05c6 100644
--- a/library/alarmserver.cpp
+++ b/library/alarmserver.cpp
@@ -1,28 +1,28 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of 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> 22#include <qfile.h>
23#include <qmessagebox.h> 23#include <qmessagebox.h>
24#include <qtextstream.h> 24#include <qtextstream.h>
25 25
26 26
27#include "qpeapplication.h" 27#include "qpeapplication.h"
28#include "global.h" 28#include "global.h"
@@ -173,48 +173,50 @@ static bool triggerAtd( bool writeHWClock = FALSE )
173 trigger.close(); 173 trigger.close();
174 QFile::remove( trigger.name() ); 174 QFile::remove( trigger.name() );
175 return FALSE; 175 return FALSE;
176 } 176 }
177 return TRUE; 177 return TRUE;
178 } 178 }
179 return FALSE; 179 return FALSE;
180} 180}
181 181
182void TimerReceiverObject::deleteTimer() 182void TimerReceiverObject::deleteTimer()
183{ 183{
184 if ( !atfilename.isEmpty() ) { 184 if ( !atfilename.isEmpty() ) {
185 unlink( atfilename ); 185 unlink( atfilename );
186 atfilename = QString::null; 186 atfilename = QString::null;
187 triggerAtd( FALSE ); 187 triggerAtd( FALSE );
188 } 188 }
189} 189}
190 190
191void TimerReceiverObject::resetTimer() 191void TimerReceiverObject::resetTimer()
192{ 192{
193 const int maxsecs = 2147000; 193 const int maxsecs = 2147000;
194 int total_written; 194 int total_written;
195 QDateTime nearest = TimeConversion::fromUTC(nearestTimerEvent->UTCtime); 195 QDateTime nearest = TimeConversion::fromUTC(nearestTimerEvent->UTCtime);
196 QDateTime now = QDateTime::currentDateTime(); 196 QDateTime now = QDateTime::currentDateTime();
197 if ( nearest < now )
198 nearest = now;
197 int secs = TimeConversion::secsTo( now, nearest ); 199 int secs = TimeConversion::secsTo( now, nearest );
198 if ( secs > maxsecs ) { 200 if ( secs > maxsecs ) {
199 // too far for millisecond timing 201 // too far for millisecond timing
200 secs = maxsecs; 202 secs = maxsecs;
201 } 203 }
202 204
203 // System timer (needed so that we wake from deep sleep), 205 // System timer (needed so that we wake from deep sleep),
204 // from the Epoch in seconds. 206 // from the Epoch in seconds.
205 // 207 //
206 int at_secs = TimeConversion::toUTC(nearest); 208 int at_secs = TimeConversion::toUTC(nearest);
207 // qDebug("reset timer to %d seconds from Epoch",at_secs); 209 // qDebug("reset timer to %d seconds from Epoch",at_secs);
208 QString fn = atdir + QString::number(at_secs) + "." 210 QString fn = atdir + QString::number(at_secs) + "."
209 + QString::number(getpid()); 211 + QString::number(getpid());
210 if ( fn != atfilename ) { 212 if ( fn != atfilename ) {
211 QFile atfile(fn+".new"); 213 QFile atfile(fn+".new");
212 if ( atfile.open(IO_WriteOnly|IO_Raw) ) { 214 if ( atfile.open(IO_WriteOnly|IO_Raw) ) {
213 // just wake up and delete the at file 215 // just wake up and delete the at file
214 QString cmd = "#!/bin/sh\nrm " + fn; 216 QString cmd = "#!/bin/sh\nrm " + fn;
215 total_written = atfile.writeBlock(cmd.latin1(),cmd.length()); 217 total_written = atfile.writeBlock(cmd.latin1(),cmd.length());
216 if ( total_written != int(cmd.length()) ) { 218 if ( total_written != int(cmd.length()) ) {
217 QMessageBox::critical( 0, tr("Out of Space"), 219 QMessageBox::critical( 0, tr("Out of Space"),
218 tr("Unable to schedule alarm.\n" 220 tr("Unable to schedule alarm.\n"
219 "Please free up space and try again") ); 221 "Please free up space and try again") );
220 atfile.close(); 222 atfile.close();
@@ -224,153 +226,178 @@ void TimerReceiverObject::resetTimer()
224 atfile.close(); 226 atfile.close();
225 unlink( atfilename ); 227 unlink( atfilename );
226 QDir d; d.rename(fn+".new",fn); 228 QDir d; d.rename(fn+".new",fn);
227 chmod(fn.latin1(),0755); 229 chmod(fn.latin1(),0755);
228 atfilename = fn; 230 atfilename = fn;
229 triggerAtd( FALSE ); 231 triggerAtd( FALSE );
230 } else { 232 } else {
231 qWarning("Cannot open atd file %s",fn.latin1()); 233 qWarning("Cannot open atd file %s",fn.latin1());
232 } 234 }
233 } 235 }
234 // Qt timers (does the actual alarm) 236 // Qt timers (does the actual alarm)
235 // from now in milliseconds 237 // from now in milliseconds
236 // 238 //
237 qDebug("AlarmServer waiting %d seconds",secs); 239 qDebug("AlarmServer waiting %d seconds",secs);
238 startTimer( 1000 * secs + 500 ); 240 startTimer( 1000 * secs + 500 );
239} 241}
240 242
241void TimerReceiverObject::timerEvent( QTimerEvent * ) 243void TimerReceiverObject::timerEvent( QTimerEvent * )
242{ 244{
243 bool needSave = FALSE; 245 bool needSave = FALSE;
244 killTimers(); 246 killTimers();
245 if (nearestTimerEvent) { 247 if (nearestTimerEvent) {
246 if ( nearestTimerEvent->UTCtime 248 if ( nearestTimerEvent->UTCtime
247 <= TimeConversion::toUTC(QDateTime::currentDateTime()) ) { 249 <= TimeConversion::toUTC(QDateTime::currentDateTime()) ) {
250#ifndef QT_NO_COP
248 QCopEnvelope e( nearestTimerEvent->channel, 251 QCopEnvelope e( nearestTimerEvent->channel,
249 nearestTimerEvent->message ); 252 nearestTimerEvent->message );
250 e << TimeConversion::fromUTC( nearestTimerEvent->UTCtime ) 253 e << TimeConversion::fromUTC( nearestTimerEvent->UTCtime )
251 << nearestTimerEvent->data; 254 << nearestTimerEvent->data;
255#endif
252 timerEventList.remove( nearestTimerEvent ); 256 timerEventList.remove( nearestTimerEvent );
253 needSave = TRUE; 257 needSave = TRUE;
254 } 258 }
255 setNearestTimerEvent(); 259 setNearestTimerEvent();
256 } else { 260 } else {
257 resetTimer(); 261 resetTimer();
258 } 262 }
259 if ( needSave ) 263 if ( needSave )
260 saveState(); 264 saveState();
261} 265}
262 266
263/*! 267/*!
264 \class AlarmServer alarmserver.h 268 \class AlarmServer alarmserver.h
265 \brief The AlarmServer class provides alarms to be scheduled. 269 \brief The AlarmServer class allows alarms to be scheduled and unscheduled.
270
271 Applications can schedule alarms with addAlarm() and can
272 unschedule alarms with deleteAlarm(). When the time for an alarm
273 to go off is reached the specified \link qcop.html QCop\endlink
274 message is sent on the specified channel (optionally with
275 additional data).
276
277 Scheduling an alarm using this class is important (rather just using
278 a QTimer) since the machine may be asleep and needs to get woken up using
279 the Linux kernel which implements this at the kernel level to minimize
280 battery usage while asleep.
266 281
267 Applications which wish to be informed when a certain time instant 282 \ingroup qtopiaemb
268 passes use the functions of AlarmServer to request so. 283 \sa QCopEnvelope
269*/ 284*/
270 285
271/*! 286/*!
272 Schedules an alarm for \a when. Soon after this time, 287 Schedules an alarm to go off at (or soon after) time \a when. When
273 \a message will be sent to \a channel, with \a data as 288 the alarm goes off, the \link qcop.html QCop\endlink \a message will
274 a parameter. \a message must be of the form "someMessage(int)". 289 be sent to \a channel, with \a data as a parameter.
290
291 If this function is called with exactly the same data as a previous
292 call the subsequent call is ignored, so there is only ever one alarm
293 with a given set of parameters.
275 294
276 \sa deleteAlarm() 295 \sa deleteAlarm()
277*/ 296*/
278void AlarmServer::addAlarm ( QDateTime when, const QCString& channel, 297void AlarmServer::addAlarm ( QDateTime when, const QCString& channel,
279 const QCString& message, int data) 298 const QCString& message, int data)
280{ 299{
281 if ( qApp->type() == QApplication::GuiServer ) { 300 if ( qApp->type() == QApplication::GuiServer ) {
282 bool needSave = FALSE; 301 bool needSave = FALSE;
283 // Here we are the server so either it has been directly called from 302 // Here we are the server so either it has been directly called from
284 // within the server or it has been sent to us from a client via QCop 303 // within the server or it has been sent to us from a client via QCop
285 if (!timerEventReceiver) 304 if (!timerEventReceiver)
286 timerEventReceiver = new TimerReceiverObject; 305 timerEventReceiver = new TimerReceiverObject;
287 306
288 timerEventItem *newTimerEventItem = new timerEventItem; 307 timerEventItem *newTimerEventItem = new timerEventItem;
289 newTimerEventItem->UTCtime = TimeConversion::toUTC( when ); 308 newTimerEventItem->UTCtime = TimeConversion::toUTC( when );
290 newTimerEventItem->channel = channel; 309 newTimerEventItem->channel = channel;
291 newTimerEventItem->message = message; 310 newTimerEventItem->message = message;
292 newTimerEventItem->data = data; 311 newTimerEventItem->data = data;
293 // explore the case of already having the event in here... 312 // explore the case of already having the event in here...
294 QListIterator<timerEventItem> it( timerEventList ); 313 QListIterator<timerEventItem> it( timerEventList );
295 for ( ; *it; ++it ) 314 for ( ; *it; ++it )
296 if ( *(*it) == *newTimerEventItem ) 315 if ( *(*it) == *newTimerEventItem )
297 return; 316 return;
298 // if we made it here, it is okay to add the item... 317 // if we made it here, it is okay to add the item...
299 timerEventList.append( newTimerEventItem ); 318 timerEventList.append( newTimerEventItem );
300 needSave = TRUE; 319 needSave = TRUE;
301 // quicker than using setNearestTimerEvent() 320 // quicker than using setNearestTimerEvent()
302 if ( nearestTimerEvent ) { 321 if ( nearestTimerEvent ) {
303 if (newTimerEventItem->UTCtime < nearestTimerEvent->UTCtime) { 322 if (newTimerEventItem->UTCtime < nearestTimerEvent->UTCtime) {
304 nearestTimerEvent = newTimerEventItem; 323 nearestTimerEvent = newTimerEventItem;
305 timerEventReceiver->killTimers(); 324 timerEventReceiver->killTimers();
306 timerEventReceiver->resetTimer(); 325 timerEventReceiver->resetTimer();
307 } 326 }
308 } else { 327 } else {
309 nearestTimerEvent = newTimerEventItem; 328 nearestTimerEvent = newTimerEventItem;
310 timerEventReceiver->resetTimer(); 329 timerEventReceiver->resetTimer();
311 } 330 }
312 if ( needSave ) 331 if ( needSave )
313 saveState(); 332 saveState();
314 } else { 333 } else {
334#ifndef QT_NO_COP
315 QCopEnvelope e( "QPE/System", "addAlarm(QDateTime,QCString,QCString,int)" ); 335 QCopEnvelope e( "QPE/System", "addAlarm(QDateTime,QCString,QCString,int)" );
316 e << when << channel << message << data; 336 e << when << channel << message << data;
337#endif
317 } 338 }
318} 339}
319 340
320/*! 341/*!
321 Deletes previously scheduled alarms which match \a when, \a channel, \a message, 342 Deletes previously scheduled alarms which match \a when, \a channel,
322 and \a data. 343 \a message, and \a data.
323 344
324 Passing null values for \a when, \a channel, or \a message indicates "any". 345 Passing null values for \a when, \a channel, or for the \link
325 Passing -1 for \a data indicates "any". 346 qcop.html QCop\endlink \a message, acts as a wildcard meaning "any".
347 Similarly, passing -1 for \a data indicates "any".
348
349 If there is no matching alarm, nothing happens.
350
351 \sa addAlarm()
326 352
327 \sa deleteAlarm()
328*/ 353*/
329void AlarmServer::deleteAlarm (QDateTime when, const QCString& channel, const QCString& message, int data) 354void AlarmServer::deleteAlarm (QDateTime when, const QCString& channel, const QCString& message, int data)
330{ 355{
331 if ( qApp->type() == QApplication::GuiServer) { 356 if ( qApp->type() == QApplication::GuiServer) {
332 bool needSave = FALSE; 357 bool needSave = FALSE;
333 if ( timerEventReceiver != NULL ) { 358 if ( timerEventReceiver != NULL ) {
334 timerEventReceiver->killTimers(); 359 timerEventReceiver->killTimers();
335 360
336 // iterate over the list of events 361 // iterate over the list of events
337 QListIterator<timerEventItem> it( timerEventList ); 362 QListIterator<timerEventItem> it( timerEventList );
338 time_t deleteTime = TimeConversion::toUTC( when ); 363 time_t deleteTime = TimeConversion::toUTC( when );
339 for ( ; *it; ++it ) { 364 for ( ; *it; ++it ) {
340 // if its a match, delete it 365 // if its a match, delete it
341 if ( ( (*it)->UTCtime == deleteTime || when.isNull() ) 366 if ( ( (*it)->UTCtime == deleteTime || when.isNull() )
342 && ( channel.isNull() || (*it)->channel == channel ) 367 && ( channel.isNull() || (*it)->channel == channel )
343 && ( message.isNull() || (*it)->message == message ) 368 && ( message.isNull() || (*it)->message == message )
344 && ( data==-1 || (*it)->data == data ) ) 369 && ( data==-1 || (*it)->data == data ) )
345 { 370 {
346 // if it's first, then we need to update the timer 371 // if it's first, then we need to update the timer
347 if ( (*it) == nearestTimerEvent ) { 372 if ( (*it) == nearestTimerEvent ) {
348 timerEventList.remove(*it); 373 timerEventList.remove(*it);
349 setNearestTimerEvent(); 374 setNearestTimerEvent();
350 } else { 375 } else {
351 timerEventList.remove(*it); 376 timerEventList.remove(*it);
352 } 377 }
353 needSave = TRUE; 378 needSave = TRUE;
354 } 379 }
355 } 380 }
356 if ( nearestTimerEvent ) 381 if ( nearestTimerEvent )
357 timerEventReceiver->resetTimer(); 382 timerEventReceiver->resetTimer();
358 } 383 }
359 if ( needSave ) 384 if ( needSave )
360 saveState(); 385 saveState();
361 } else { 386 } else {
387#ifndef QT_NO_COP
362 QCopEnvelope e( "QPE/System", "deleteAlarm(QDateTime,QCString,QCString,int)" ); 388 QCopEnvelope e( "QPE/System", "deleteAlarm(QDateTime,QCString,QCString,int)" );
363 e << when << channel << message << data; 389 e << when << channel << message << data;
390#endif
364 } 391 }
365} 392}
366 393
367/*! 394/*!
368 Writes the system clock to the hardware clock. 395 Writes the system clock to the hardware clock.
369*/ 396*/
370void Global::writeHWClock() 397void Global::writeHWClock()
371{ 398{
372 if ( !triggerAtd( TRUE ) ) { 399 if ( !triggerAtd( TRUE ) ) {
373 // atd not running? set it ourselves 400 // atd not running? set it ourselves
374 system("/sbin/hwclock --systohc"); // ##### UTC? 401 system("/sbin/hwclock --systohc"); // ##### UTC?
375 } 402 }
376} 403}