1 /*----------------------------------------------------------------------------
2 --
3 --  Module:           xtmUpdate
4 --
5 --  Project:          Xdiary
6 --  System:           xtm - X Desktop Calendar
7 --    Subsystem:      <>
8 --    Function block: <>
9 --
10 --  Description:
11 --    Centralize update management. Various sources of update requests
12 --    can be managed.
13 --
14 --  Filename:         xtmUpdate.c
15 --
16 --  Authors:          Roger Larsson, Ulrika Bornetun
17 --  Creation date:    1991-04-01
18 --
19 --
20 --  (C) Copyright Ulrika Bornetun, Roger Larsson (1995)
21 --      All rights reserved
22 --
23 --  Permission to use, copy, modify, and distribute this software and its
24 --  documentation for any purpose and without fee is hereby granted,
25 --  provided that the above copyright notice appear in all copies. Ulrika
26 --  Bornetun and Roger Larsson make no representations about the usability
27 --  of this software for any purpose. It is provided "as is" without express
28 --  or implied warranty.
29 ----------------------------------------------------------------------------*/
30 
31 /* SCCS module identifier. */
32 static char SCCSID[] = "@(#) Module: xtmUpdate.c, Version: 1.1, Date: 95/02/18 15:52:54";
33 
34 
35 /*----------------------------------------------------------------------------
36 --  Include files
37 ----------------------------------------------------------------------------*/
38 
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 
43 #include <X11/Intrinsic.h>
44 
45 #include "System.h"
46 #include "TimDate.h"
47 
48 #include "xtmUpdate.h"
49 
50 
51 /*----------------------------------------------------------------------------
52 --  Macro definitions
53 ----------------------------------------------------------------------------*/
54 
55 #define  MAX_UPDATE_REG  200
56 
57 
58 /*----------------------------------------------------------------------------
59 --  Type declarations
60 ----------------------------------------------------------------------------*/
61 
62 typedef struct {
63 
64   /* Id of the update function (unique). If 0, slot is free. */
65   UINT32  id;
66 
67   /* Call the update function when one of the following happens. */
68   UINT32  action_flags;
69 
70   /* Function to call. */
71   XTM_UP_UPDATE_CB  updateCB;
72 
73   /* User data. */
74   void  *user_data;
75 
76 } UPDATE_REC, *UPDATE_REC_REF;
77 
78 
79 /*----------------------------------------------------------------------------
80 --  Global definitions
81 ----------------------------------------------------------------------------*/
82 
83 /* Name of module. */
84 static char  *module_name = "xtmUpdate";
85 
86 /* Unique ID counter. */
87 static  int  unique_id = 0;
88 
89 /* Delta time in munites for refresh calls. */
90 static  int  refresh_min;
91 
92 /* The last time checked. */
93 static  TIM_TIME_REF  last_check = 0;
94 
95 /* Our update DB. */
96 static  UPDATE_REC  updateDb[ MAX_UPDATE_REG ];
97 
98 
99 /*----------------------------------------------------------------------------
100 --  Function prototypes
101 ----------------------------------------------------------------------------*/
102 
103 static void
104   minuteTimer( XtAppContext  context );
105 
106 static void
107   refreshTimer( XtAppContext  context );
108 
109 
110 
111 /*----------------------------------------------------------------------------
112 --  Functions
113 ----------------------------------------------------------------------------*/
114 
115 void
xtmUpDoUpdate(UINT32 flags,void * update_user_data)116   xtmUpDoUpdate( UINT32  flags,
117                  void    *update_user_data )
118 {
119 
120   /* Variables. */
121   int  index;
122 
123 
124   /* Code. */
125 
126   /* Do we have a registred callback? */
127   for( index = 0; index < MAX_UPDATE_REG; index++ ) {
128 
129     /* Correct pattern. */
130     if( updateDb[ index ].id != 0 &&
131         flagIsSet( updateDb[ index ].action_flags, flags ) ) {
132 
133       /* Call the callback. */
134       (* updateDb[ index ].updateCB)( flags,
135                                       updateDb[ index ].user_data,
136                                       update_user_data );
137 
138     } /* if */
139 
140   } /* loop */
141 
142 
143   return;
144 
145 } /* xtmUpDoUpdate */
146 
147 
148 /*----------------------------------------------------------------------*/
149 
150 void
xtmUpInitialize(XtAppContext context,int refresh_delta)151   xtmUpInitialize( XtAppContext  context,
152                    int           refresh_delta )
153 {
154 
155   /* Variables. */
156   int  index;
157 
158 
159   /* Code. */
160 
161   /* No callbacks registered. */
162   for( index = 0; index < MAX_UPDATE_REG; index++ )
163     updateDb[ index ].id = 0;
164 
165 
166   /* Start the minute timer. */
167   minuteTimer( context );
168 
169   /* Start the refresh timer. */
170   refresh_min = refresh_delta;
171 
172   if( refresh_min > 0 )
173     refreshTimer( context );
174 
175 
176   return;
177 
178 } /* xtmUpInitialize */
179 
180 
181 /*----------------------------------------------------------------------*/
182 
183 UINT32
xtmUpRegister(UINT32 flags,XTM_UP_UPDATE_CB updateCB,void * user_data)184   xtmUpRegister( UINT32            flags,
185                  XTM_UP_UPDATE_CB  updateCB,
186                  void              *user_data )
187 {
188 
189   /* Variables. */
190   int  index;
191 
192 
193   /* Code. */
194 
195   /* Any free slots? */
196   for( index = 0; index < MAX_UPDATE_REG; index++ ) {
197     if( updateDb[ index ].id == 0 )
198       break;
199   }
200 
201   if( index == MAX_UPDATE_REG )
202     return( 0 );
203 
204 
205   /* Save the update data. */
206   unique_id++;
207 
208   updateDb[ index ].id           = unique_id;
209   updateDb[ index ].action_flags = flags;
210   updateDb[ index ].updateCB     = updateCB;
211   updateDb[ index ].user_data    = user_data;
212 
213 
214   return( unique_id );
215 
216 } /* xtmUpRegister */
217 
218 
219 /*----------------------------------------------------------------------*/
220 
221 void
xtmUpRemove(UINT32 id)222   xtmUpRemove( UINT32  id )
223 {
224 
225   /* Variables. */
226   int  index;
227 
228 
229   /* Code. */
230 
231   /* Find the registered id. */
232   for( index = 0; index < MAX_UPDATE_REG; index++ ) {
233 
234     if( updateDb[ index ].id == id ) {
235       updateDb[ index ].id = 0;
236 
237       return;
238     }
239 
240   } /* loop */
241 
242 
243   return;
244 
245 } /* xtmUpRemove */
246 
247 
248 /*----------------------------------------------------------------------*/
249 
250 static void
minuteTimer(XtAppContext context)251   minuteTimer( XtAppContext  context )
252 {
253 
254   /* Variables. */
255   int           flags = 0;
256   int           next_minute;
257   TIM_TIME_REF  now;
258 
259 
260   /* Code. */
261 
262   now = TimLocalTime( TimMakeTimeNow() );
263 
264   /* Do we have a new day? */
265   if( last_check != 0 ) {
266     if( TimIsSameDate( now, last_check ) != TIM_YES )
267       flagSet( flags, XTM_UP_NEW_DAY );
268   }
269 
270 
271   /* Call the update function. */
272   flagSet( flags, XTM_UP_MINUTE_TICK );
273 
274   xtmUpDoUpdate( flags, NULL );
275 
276 
277   last_check = now;
278 
279   /* Schedule the next wakeup call. */
280   next_minute = (60 - now % 60) * 1000;
281 
282   XtAppAddTimeOut( context, next_minute,
283                    (XtTimerCallbackProc) minuteTimer, (XtPointer) context );
284 
285 
286   return;
287 
288 } /* minuteTimer */
289 
290 
291 /*----------------------------------------------------------------------*/
292 
293 static void
refreshTimer(XtAppContext context)294   refreshTimer( XtAppContext  context )
295 {
296 
297   /* Variables. */
298   int           next_call;
299   TIM_TIME_REF  now;
300 
301 
302   /* Code. */
303 
304   now = TimLocalTime( TimMakeTimeNow() );
305 
306 
307   /* Call the update function. */
308   xtmUpDoUpdate( XTM_UP_REFRESH_TICK, NULL );
309 
310 
311   /* Schedule the next wakeup call. */
312   next_call = (refresh_min - 1) * 60 * 1000 + (60 - now % 60) * 1000;
313 
314   XtAppAddTimeOut( context, next_call,
315                    (XtTimerCallbackProc) refreshTimer, (XtPointer) context );
316 
317 
318   return;
319 
320 } /* refreshTimer */
321 
322 
323