summaryrefslogtreecommitdiff
path: root/library/alarmserver.cpp
Unidiff
Diffstat (limited to 'library/alarmserver.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/alarmserver.cpp2
1 files changed, 1 insertions, 1 deletions
diff --git a/library/alarmserver.cpp b/library/alarmserver.cpp
index 02bca3d..7e6e515 100644
--- a/library/alarmserver.cpp
+++ b/library/alarmserver.cpp
@@ -33,257 +33,257 @@
33#include <qpe/timeconversion.h> 33#include <qpe/timeconversion.h>
34 34
35#include <sys/types.h> 35#include <sys/types.h>
36#include <sys/stat.h> 36#include <sys/stat.h>
37 37
38#include <stdlib.h> 38#include <stdlib.h>
39#include <unistd.h> 39#include <unistd.h>
40 40
41struct timerEventItem { 41struct timerEventItem {
42 time_t UTCtime; 42 time_t UTCtime;
43 QCString channel, message; 43 QCString channel, message;
44 int data; 44 int data;
45 bool operator==( const timerEventItem &right ) const 45 bool operator==( const timerEventItem &right ) const
46 { 46 {
47 return ( UTCtime == right.UTCtime 47 return ( UTCtime == right.UTCtime
48 && channel == right.channel 48 && channel == right.channel
49 && message == right.message 49 && message == right.message
50 && data == right.data ); 50 && data == right.data );
51 } 51 }
52}; 52};
53 53
54class TimerReceiverObject : public QObject 54class TimerReceiverObject : public QObject
55{ 55{
56public: 56public:
57 TimerReceiverObject() { } 57 TimerReceiverObject() { }
58 ~TimerReceiverObject() { } 58 ~TimerReceiverObject() { }
59 void resetTimer(); 59 void resetTimer();
60 void setTimerEventItem(); 60 void setTimerEventItem();
61 void deleteTimer(); 61 void deleteTimer();
62protected: 62protected:
63 void timerEvent( QTimerEvent *te ); 63 void timerEvent( QTimerEvent *te );
64private: 64private:
65 QString atfilename; 65 QString atfilename;
66}; 66};
67 67
68TimerReceiverObject *timerEventReceiver = NULL; 68TimerReceiverObject *timerEventReceiver = NULL;
69QList<timerEventItem> timerEventList; 69QList<timerEventItem> timerEventList;
70timerEventItem *nearestTimerEvent = NULL; 70timerEventItem *nearestTimerEvent = NULL;
71 71
72 72
73// set the timer to go off on the next event in the list 73// set the timer to go off on the next event in the list
74void setNearestTimerEvent() 74void setNearestTimerEvent()
75{ 75{
76 nearestTimerEvent = NULL; 76 nearestTimerEvent = NULL;
77 QListIterator<timerEventItem> it( timerEventList ); 77 QListIterator<timerEventItem> it( timerEventList );
78 if ( *it ) 78 if ( *it )
79 nearestTimerEvent = *it; 79 nearestTimerEvent = *it;
80 for ( ; *it; ++it ) 80 for ( ; *it; ++it )
81 if ( (*it)->UTCtime < nearestTimerEvent->UTCtime ) 81 if ( (*it)->UTCtime < nearestTimerEvent->UTCtime )
82 nearestTimerEvent = *it; 82 nearestTimerEvent = *it;
83 if (nearestTimerEvent) 83 if (nearestTimerEvent)
84 timerEventReceiver->resetTimer(); 84 timerEventReceiver->resetTimer();
85 else 85 else
86 timerEventReceiver->deleteTimer(); 86 timerEventReceiver->deleteTimer();
87} 87}
88 88
89 89
90//store current state to file 90//store current state to file
91//Simple implementation. Should run on a timer. 91//Simple implementation. Should run on a timer.
92 92
93static void saveState() 93static void saveState()
94{ 94{
95 QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" ); 95 QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" );
96 if ( timerEventList.isEmpty() ) { 96 if ( timerEventList.isEmpty() ) {
97 unlink( savefilename ); 97 unlink( savefilename );
98 return; 98 return;
99 } 99 }
100 100
101 QFile savefile(savefilename+".new"); 101 QFile savefile(savefilename+".new");
102 if ( savefile.open(IO_WriteOnly) ) { 102 if ( savefile.open(IO_WriteOnly) ) {
103 QDataStream ds( &savefile ); 103 QDataStream ds( &savefile );
104 104
105 //save 105 //save
106 106
107 QListIterator<timerEventItem> it( timerEventList ); 107 QListIterator<timerEventItem> it( timerEventList );
108 for ( ; *it; ++it ) { 108 for ( ; *it; ++it ) {
109 ds << it.current()->UTCtime; 109 ds << it.current()->UTCtime;
110 ds << it.current()->channel; 110 ds << it.current()->channel;
111 ds << it.current()->message; 111 ds << it.current()->message;
112 ds << it.current()->data; 112 ds << it.current()->data;
113 } 113 }
114 114
115 115
116 savefile.close(); 116 savefile.close();
117 unlink( savefilename ); 117 unlink( savefilename );
118 QDir d; d.rename(savefilename+".new",savefilename); 118 QDir d; d.rename(savefilename+".new",savefilename);
119 119
120 } 120 }
121} 121}
122 122
123/*! 123/*!
124 Sets up the alarm server. Restoring to previous state (session management). 124 Sets up the alarm server. Restoring to previous state (session management).
125 */ 125 */
126void AlarmServer::initialize() 126void AlarmServer::initialize()
127{ 127{
128 //read autosave file and put events in timerEventList 128 //read autosave file and put events in timerEventList
129 129
130 QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" ); 130 QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" );
131 131
132 QFile savefile(savefilename); 132 QFile savefile(savefilename);
133 if ( savefile.open(IO_ReadOnly) ) { 133 if ( savefile.open(IO_ReadOnly) ) {
134 QDataStream ds( &savefile ); 134 QDataStream ds( &savefile );
135 while ( !ds.atEnd() ) { 135 while ( !ds.atEnd() ) {
136 timerEventItem *newTimerEventItem = new timerEventItem; 136 timerEventItem *newTimerEventItem = new timerEventItem;
137 ds >> newTimerEventItem->UTCtime; 137 ds >> newTimerEventItem->UTCtime;
138 ds >> newTimerEventItem->channel; 138 ds >> newTimerEventItem->channel;
139 ds >> newTimerEventItem->message; 139 ds >> newTimerEventItem->message;
140 ds >> newTimerEventItem->data; 140 ds >> newTimerEventItem->data;
141 timerEventList.append( newTimerEventItem ); 141 timerEventList.append( newTimerEventItem );
142 } 142 }
143 savefile.close(); 143 savefile.close();
144 if (!timerEventReceiver) 144 if (!timerEventReceiver)
145 timerEventReceiver = new TimerReceiverObject; 145 timerEventReceiver = new TimerReceiverObject;
146 setNearestTimerEvent(); 146 setNearestTimerEvent();
147 } 147 }
148} 148}
149 149
150 150
151 151
152 152
153static const char* atdir = "/var/spool/at/"; 153static const char* atdir = "/var/spool/at/";
154 154
155static bool triggerAtd( bool writeHWClock = FALSE ) 155static bool triggerAtd( bool writeHWClock = FALSE )
156{ 156{
157 QFile trigger(QString(atdir) + "trigger"); 157 QFile trigger(QString(atdir) + "trigger");
158 if ( trigger.open(IO_WriteOnly|IO_Raw) ) { 158 if ( trigger.open(IO_WriteOnly|IO_Raw) ) {
159 159
160 const char* data = 160 const char* data =
161#ifdef QT_QWS_CUSTOM 161#ifdef QT_QWS_SHARP
162 //custom atd only writes HW Clock if we write a 'W' 162 //custom atd only writes HW Clock if we write a 'W'
163 ( writeHWClock ) ? "W\n" : 163 ( writeHWClock ) ? "W\n" :
164#endif 164#endif
165 data = "\n"; 165 data = "\n";
166 int len = strlen(data); 166 int len = strlen(data);
167 int total_written = trigger.writeBlock(data,len); 167 int total_written = trigger.writeBlock(data,len);
168 if ( total_written != len ) { 168 if ( total_written != len ) {
169 QMessageBox::critical( 0, QObject::tr( "Out of Space" ), 169 QMessageBox::critical( 0, QObject::tr( "Out of Space" ),
170 QObject::tr( "Unable to schedule alarm.\nFree some memory and try again." ) ); 170 QObject::tr( "Unable to schedule alarm.\nFree some memory and try again." ) );
171 trigger.close(); 171 trigger.close();
172 QFile::remove( trigger.name() ); 172 QFile::remove( trigger.name() );
173 return FALSE; 173 return FALSE;
174 } 174 }
175 return TRUE; 175 return TRUE;
176 } 176 }
177 return FALSE; 177 return FALSE;
178} 178}
179 179
180void TimerReceiverObject::deleteTimer() 180void TimerReceiverObject::deleteTimer()
181{ 181{
182 if ( !atfilename.isEmpty() ) { 182 if ( !atfilename.isEmpty() ) {
183 unlink( atfilename ); 183 unlink( atfilename );
184 atfilename = QString::null; 184 atfilename = QString::null;
185 triggerAtd( FALSE ); 185 triggerAtd( FALSE );
186 } 186 }
187} 187}
188 188
189void TimerReceiverObject::resetTimer() 189void TimerReceiverObject::resetTimer()
190{ 190{
191 const int maxsecs = 2147000; 191 const int maxsecs = 2147000;
192 int total_written; 192 int total_written;
193 QDateTime nearest = TimeConversion::fromUTC(nearestTimerEvent->UTCtime); 193 QDateTime nearest = TimeConversion::fromUTC(nearestTimerEvent->UTCtime);
194 QDateTime now = QDateTime::currentDateTime(); 194 QDateTime now = QDateTime::currentDateTime();
195 if ( nearest < now ) 195 if ( nearest < now )
196 nearest = now; 196 nearest = now;
197 int secs = TimeConversion::secsTo( now, nearest ); 197 int secs = TimeConversion::secsTo( now, nearest );
198 if ( secs > maxsecs ) { 198 if ( secs > maxsecs ) {
199 // too far for millisecond timing 199 // too far for millisecond timing
200 secs = maxsecs; 200 secs = maxsecs;
201 } 201 }
202 202
203 // System timer (needed so that we wake from deep sleep), 203 // System timer (needed so that we wake from deep sleep),
204 // from the Epoch in seconds. 204 // from the Epoch in seconds.
205 // 205 //
206 int at_secs = TimeConversion::toUTC(nearest); 206 int at_secs = TimeConversion::toUTC(nearest);
207 // qDebug("reset timer to %d seconds from Epoch",at_secs); 207 // qDebug("reset timer to %d seconds from Epoch",at_secs);
208 QString fn = atdir + QString::number(at_secs) + "." 208 QString fn = atdir + QString::number(at_secs) + "."
209 + QString::number(getpid()); 209 + QString::number(getpid());
210 if ( fn != atfilename ) { 210 if ( fn != atfilename ) {
211 QFile atfile(fn+".new"); 211 QFile atfile(fn+".new");
212 if ( atfile.open(IO_WriteOnly|IO_Raw) ) { 212 if ( atfile.open(IO_WriteOnly|IO_Raw) ) {
213 // just wake up and delete the at file 213 // just wake up and delete the at file
214 QString cmd = "#!/bin/sh\nrm " + fn; 214 QString cmd = "#!/bin/sh\nrm " + fn;
215 total_written = atfile.writeBlock(cmd.latin1(),cmd.length()); 215 total_written = atfile.writeBlock(cmd.latin1(),cmd.length());
216 if ( total_written != int(cmd.length()) ) { 216 if ( total_written != int(cmd.length()) ) {
217 QMessageBox::critical( 0, tr("Out of Space"), 217 QMessageBox::critical( 0, tr("Out of Space"),
218 tr("Unable to schedule alarm.\n" 218 tr("Unable to schedule alarm.\n"
219 "Please free up space and try again") ); 219 "Please free up space and try again") );
220 atfile.close(); 220 atfile.close();
221 QFile::remove( atfile.name() ); 221 QFile::remove( atfile.name() );
222 return; 222 return;
223 } 223 }
224 atfile.close(); 224 atfile.close();
225 unlink( atfilename ); 225 unlink( atfilename );
226 QDir d; d.rename(fn+".new",fn); 226 QDir d; d.rename(fn+".new",fn);
227 chmod(fn.latin1(),0755); 227 chmod(fn.latin1(),0755);
228 atfilename = fn; 228 atfilename = fn;
229 triggerAtd( FALSE ); 229 triggerAtd( FALSE );
230 } else { 230 } else {
231 qWarning("Cannot open atd file %s",fn.latin1()); 231 qWarning("Cannot open atd file %s",fn.latin1());
232 } 232 }
233 } 233 }
234 // Qt timers (does the actual alarm) 234 // Qt timers (does the actual alarm)
235 // from now in milliseconds 235 // from now in milliseconds
236 // 236 //
237 qDebug("AlarmServer waiting %d seconds",secs); 237 qDebug("AlarmServer waiting %d seconds",secs);
238 startTimer( 1000 * secs + 500 ); 238 startTimer( 1000 * secs + 500 );
239} 239}
240 240
241void TimerReceiverObject::timerEvent( QTimerEvent * ) 241void TimerReceiverObject::timerEvent( QTimerEvent * )
242{ 242{
243 bool needSave = FALSE; 243 bool needSave = FALSE;
244 killTimers(); 244 killTimers();
245 if (nearestTimerEvent) { 245 if (nearestTimerEvent) {
246 if ( nearestTimerEvent->UTCtime 246 if ( nearestTimerEvent->UTCtime
247 <= TimeConversion::toUTC(QDateTime::currentDateTime()) ) { 247 <= TimeConversion::toUTC(QDateTime::currentDateTime()) ) {
248#ifndef QT_NO_COP 248#ifndef QT_NO_COP
249 QCopEnvelope e( nearestTimerEvent->channel, 249 QCopEnvelope e( nearestTimerEvent->channel,
250 nearestTimerEvent->message ); 250 nearestTimerEvent->message );
251 e << TimeConversion::fromUTC( nearestTimerEvent->UTCtime ) 251 e << TimeConversion::fromUTC( nearestTimerEvent->UTCtime )
252 << nearestTimerEvent->data; 252 << nearestTimerEvent->data;
253#endif 253#endif
254 timerEventList.remove( nearestTimerEvent ); 254 timerEventList.remove( nearestTimerEvent );
255 needSave = TRUE; 255 needSave = TRUE;
256 } 256 }
257 setNearestTimerEvent(); 257 setNearestTimerEvent();
258 } else { 258 } else {
259 resetTimer(); 259 resetTimer();
260 } 260 }
261 if ( needSave ) 261 if ( needSave )
262 saveState(); 262 saveState();
263} 263}
264 264
265/*! 265/*!
266 \class AlarmServer alarmserver.h 266 \class AlarmServer alarmserver.h
267 \brief The AlarmServer class allows alarms to be scheduled and unscheduled. 267 \brief The AlarmServer class allows alarms to be scheduled and unscheduled.
268 268
269 Applications can schedule alarms with addAlarm() and can 269 Applications can schedule alarms with addAlarm() and can
270 unschedule alarms with deleteAlarm(). When the time for an alarm 270 unschedule alarms with deleteAlarm(). When the time for an alarm
271 to go off is reached the specified \link qcop.html QCop\endlink 271 to go off is reached the specified \link qcop.html QCop\endlink
272 message is sent on the specified channel (optionally with 272 message is sent on the specified channel (optionally with
273 additional data). 273 additional data).
274 274
275 Scheduling an alarm using this class is important (rather just using 275 Scheduling an alarm using this class is important (rather just using
276 a QTimer) since the machine may be asleep and needs to get woken up using 276 a QTimer) since the machine may be asleep and needs to get woken up using
277 the Linux kernel which implements this at the kernel level to minimize 277 the Linux kernel which implements this at the kernel level to minimize
278 battery usage while asleep. 278 battery usage while asleep.
279 279
280 \ingroup qtopiaemb 280 \ingroup qtopiaemb
281 \sa QCopEnvelope 281 \sa QCopEnvelope
282*/ 282*/
283 283
284/*! 284/*!
285 Schedules an alarm to go off at (or soon after) time \a when. When 285 Schedules an alarm to go off at (or soon after) time \a when. When
286 the alarm goes off, the \link qcop.html QCop\endlink \a message will 286 the alarm goes off, the \link qcop.html QCop\endlink \a message will
287 be sent to \a channel, with \a data as a parameter. 287 be sent to \a channel, with \a data as a parameter.
288 288
289 If this function is called with exactly the same data as a previous 289 If this function is called with exactly the same data as a previous