2 * MMSYTEM time functions
4 * Copyright 1993 Martin Ayotte
22 static BOOL32 mmTimeStarted
= FALSE
;
23 static MMTIME16 mmSysTimeMS
;
24 static MMTIME16 mmSysTimeSMPTE
;
26 typedef struct tagTIMERENTRY
{
30 HINSTANCE32 hInstance
;
36 struct tagTIMERENTRY
*Next
;
38 } TIMERENTRY
, *LPTIMERENTRY
;
40 static LPTIMERENTRY lpTimerList
= NULL
;
44 * is this the minimum resolution ?
46 /*#define MMSYSTIME_MININTERVAL (33)*/
47 #define MMSYSTIME_MININTERVAL (31)
48 #define MMSYSTIME_MAXINTERVAL (65535)
51 /**************************************************************************
54 static VOID
check_MMtimers()
56 LPTIMERENTRY lpTimer
= lpTimerList
;
57 DWORD curtick
= GetTickCount();
59 while (lpTimer
!= NULL
) {
60 if (lpTimer
->triggertime
<= curtick
) {
61 lpTimer
->wCurTime
= lpTimer
->wDelay
;
63 if (lpTimer
->lpFunc
!= (FARPROC16
) NULL
) {
64 dprintf_mmtime(stddeb
, "MMSysTimeCallback // before CallBack16 !\n");
65 dprintf_mmtime(stddeb
, "MMSysTimeCallback // lpFunc=%p wTimerID=%04X dwUser=%08lX !\n",
66 lpTimer
->lpFunc
, lpTimer
->wTimerID
, lpTimer
->dwUser
);
67 dprintf_mmtime(stddeb
, "MMSysTimeCallback // hInstance=%04X !\n", lpTimer
->hInstance
);
70 /* - TimeProc callback that is called here is something strange, under Windows 3.1x it is called
71 * during interrupt time, is allowed to execute very limited number of API calls (like
72 * PostMessage), and must reside in DLL (therefore uses stack of active application). So I
73 * guess current implementation via SetTimer has to be improved upon.
76 lpTimer
->lpFunc(lpTimer
->wTimerID
,0,lpTimer
->dwUser
,0,0);
78 Callbacks
->CallTimeFuncProc(lpTimer
->lpFunc
,
83 dprintf_mmtime(stddeb
, "MMSysTimeCallback // after CallBack16 !\n");
85 if (lpTimer
->wFlags
& TIME_ONESHOT
)
86 timeKillEvent32(lpTimer
->wTimerID
);
88 lpTimer
= lpTimer
->Next
;
92 /**************************************************************************
93 * TIME_MMSysTimeCallback
95 static VOID
TIME_MMSysTimeCallback( HWND32 hwnd
, UINT32 msg
,
96 UINT32 id
, DWORD dwTime
)
98 LPTIMERENTRY lpTimer
= lpTimerList
;
99 mmSysTimeMS
.u
.ms
+= MMSYSTIME_MININTERVAL
;
100 mmSysTimeSMPTE
.u
.smpte
.frame
++;
101 while (lpTimer
!= NULL
) {
103 if (lpTimer
->wCurTime
== 0) {
104 lpTimer
->wCurTime
= lpTimer
->wDelay
;
106 if (lpTimer
->lpFunc
!= (FARPROC16
) NULL
) {
107 dprintf_mmtime(stddeb
, "MMSysTimeCallback // before CallBack16 !\n");
108 dprintf_mmtime(stddeb
, "MMSysTimeCallback // lpFunc=%p wTimerID=%04X dwUser=%08lX !\n",
109 lpTimer
->lpFunc
, lpTimer
->wTimerID
, lpTimer
->dwUser
);
110 dprintf_mmtime(stddeb
, "MMSysTimeCallback // hInstance=%04X !\n", lpTimer
->hInstance
);
112 /* This is wrong (lpFunc is NULL all the time)
114 lpFunc = MODULE_GetEntryPoint( lpTimer->hInstance,
115 MODULE_GetOrdinal(lpTimer->hInstance,"TimerCallBack" ));
116 dprintf_mmtime(stddeb, "MMSysTimeCallback // lpFunc=%08lx !\n", lpFunc);
120 /* - TimeProc callback that is called here is something strange, under Windows 3.1x it is called
121 * during interrupt time, is allowed to execute very limited number of API calls (like
122 * PostMessage), and must reside in DLL (therefore uses stack of active application). So I
123 * guess current implementation via SetTimer has to be improved upon.
125 if (lpTimer
->iswin32
)
126 lpTimer
->lpFunc(lpTimer
->wTimerID
,0,lpTimer
->dwUser
,0,0);
128 Callbacks
->CallTimeFuncProc(lpTimer
->lpFunc
,
133 dprintf_mmtime(stddeb
, "MMSysTimeCallback // after CallBack16 !\n");
136 if (lpTimer
->wFlags
& TIME_ONESHOT
)
137 timeKillEvent32(lpTimer
->wTimerID
);
139 lpTimer
= lpTimer
->Next
;
143 /**************************************************************************
144 * StartMMTime [internal]
146 static void StartMMTime()
148 if (!mmTimeStarted
) {
149 mmTimeStarted
= TRUE
;
150 mmSysTimeMS
.wType
= TIME_MS
;
151 mmSysTimeMS
.u
.ms
= 0;
152 mmSysTimeSMPTE
.wType
= TIME_SMPTE
;
153 mmSysTimeSMPTE
.u
.smpte
.hour
= 0;
154 mmSysTimeSMPTE
.u
.smpte
.min
= 0;
155 mmSysTimeSMPTE
.u
.smpte
.sec
= 0;
156 mmSysTimeSMPTE
.u
.smpte
.frame
= 0;
157 mmSysTimeSMPTE
.u
.smpte
.fps
= 0;
158 mmSysTimeSMPTE
.u
.smpte
.dummy
= 0;
159 SetTimer32( 0, 1, MMSYSTIME_MININTERVAL
, TIME_MMSysTimeCallback
);
163 /**************************************************************************
164 * timeGetSystemTime [WINMM.140]
166 MMRESULT32 WINAPI
timeGetSystemTime32(LPMMTIME32 lpTime
, UINT32 wSize
)
168 dprintf_mmsys(stddeb
, "timeGetSystemTime32(%p, %u);\n", lpTime
, wSize
);
171 lpTime
->wType
= TIME_MS
;
172 lpTime
->u
.ms
= mmSysTimeMS
.u
.ms
;
176 /**************************************************************************
177 * timeGetSystemTime [MMSYSTEM.601]
179 MMRESULT16 WINAPI
timeGetSystemTime16(LPMMTIME16 lpTime
, UINT16 wSize
)
181 dprintf_mmsys(stddeb
, "timeGetSystemTime16(%p, %u);\n", lpTime
, wSize
);
184 lpTime
->wType
= TIME_MS
;
185 lpTime
->u
.ms
= mmSysTimeMS
.u
.ms
;
189 /**************************************************************************
190 * timeSetEvent [MMSYSTEM.602]
192 MMRESULT32 WINAPI
timeSetEvent32(UINT32 wDelay
,UINT32 wResol
,
193 LPTIMECALLBACK32 lpFunc
,DWORD dwUser
,
197 LPTIMERENTRY lpNewTimer
;
198 LPTIMERENTRY lpTimer
= lpTimerList
;
200 dprintf_mmtime(stddeb
, "timeSetEvent32(%u, %u, %p, %08lX, %04X);\n",
201 wDelay
, wResol
, lpFunc
, dwUser
, wFlags
);
204 lpNewTimer
= (LPTIMERENTRY
)xmalloc(sizeof(TIMERENTRY
));
205 if (lpNewTimer
== NULL
)
207 while (lpTimer
!= NULL
) {
208 wNewID
= MAX(wNewID
, lpTimer
->wTimerID
);
209 lpTimer
= lpTimer
->Next
;
212 lpNewTimer
->Next
= lpTimerList
;
213 lpTimerList
= lpNewTimer
;
214 lpNewTimer
->wTimerID
= wNewID
+ 1;
215 lpNewTimer
->wCurTime
= wDelay
;
216 lpNewTimer
->triggertime
= wDelay
+GetTickCount();
217 lpNewTimer
->wDelay
= wDelay
;
218 lpNewTimer
->wResol
= wResol
;
219 lpNewTimer
->lpFunc
= (FARPROC16
) lpFunc
;
220 lpNewTimer
->iswin32
= 1;
221 lpNewTimer
->hInstance
= GetTaskDS();
222 dprintf_mmtime(stddeb
, "timeSetEvent // hInstance=%04X !\n", lpNewTimer
->hInstance
);
223 dprintf_mmtime(stddeb
, "timeSetEvent // lpFunc=%p !\n",
225 lpNewTimer
->dwUser
= dwUser
;
226 lpNewTimer
->wFlags
= wFlags
;
227 return lpNewTimer
->wTimerID
;
230 /**************************************************************************
231 * timeSetEvent [MMSYSTEM.602]
233 MMRESULT16 WINAPI
timeSetEvent16(UINT16 wDelay
, UINT16 wResol
,
234 LPTIMECALLBACK16 lpFunc
,DWORD dwUser
,
238 LPTIMERENTRY lpNewTimer
;
239 LPTIMERENTRY lpTimer
= lpTimerList
;
240 dprintf_mmtime(stddeb
, "timeSetEvent(%u, %u, %p, %08lX, %04X);\n",
241 wDelay
, wResol
, lpFunc
, dwUser
, wFlags
);
244 lpNewTimer
= (LPTIMERENTRY
)xmalloc(sizeof(TIMERENTRY
));
245 if (lpNewTimer
== NULL
)
247 while (lpTimer
!= NULL
) {
248 wNewID
= MAX(wNewID
, lpTimer
->wTimerID
);
249 lpTimer
= lpTimer
->Next
;
252 lpNewTimer
->Next
= lpTimerList
;
253 lpTimerList
= lpNewTimer
;
254 lpNewTimer
->wTimerID
= wNewID
+ 1;
255 lpNewTimer
->wCurTime
= wDelay
;
256 lpNewTimer
->wDelay
= wDelay
;
257 lpNewTimer
->triggertime
= wDelay
+GetTickCount();
258 lpNewTimer
->wResol
= wResol
;
259 lpNewTimer
->lpFunc
= (FARPROC16
) lpFunc
;
260 lpNewTimer
->iswin32
= 0;
261 lpNewTimer
->hInstance
= GetTaskDS();
262 dprintf_mmtime(stddeb
, "timeSetEvent // hInstance=%04X !\n", lpNewTimer
->hInstance
);
263 dprintf_mmtime(stddeb
, "timeSetEvent // PTR_SEG_TO_LIN(lpFunc)=%p !\n",
264 PTR_SEG_TO_LIN(lpFunc
));
265 lpNewTimer
->dwUser
= dwUser
;
266 lpNewTimer
->wFlags
= wFlags
;
267 return lpNewTimer
->wTimerID
;
270 /**************************************************************************
271 * timeKillEvent [WINMM.142]
273 MMRESULT32 WINAPI
timeKillEvent32(UINT32 wID
)
275 LPTIMERENTRY xlptimer
,*lpTimer
= &lpTimerList
;
277 if (wID
== (*lpTimer
)->wTimerID
) {
278 xlptimer
= (*lpTimer
)->Next
;
283 lpTimer
= &((*lpTimer
)->Next
);
288 /**************************************************************************
289 * timeKillEvent [MMSYSTEM.603]
291 MMRESULT16 WINAPI
timeKillEvent16(UINT16 wID
)
293 return timeKillEvent32(wID
);
296 /**************************************************************************
297 * timeGetDevCaps [WINMM.139]
299 MMRESULT32 WINAPI
timeGetDevCaps32(LPTIMECAPS32 lpCaps
,UINT32 wSize
)
301 dprintf_mmtime(stddeb
, "timeGetDevCaps(%p, %u) !\n", lpCaps
, wSize
);
304 lpCaps
->wPeriodMin
= MMSYSTIME_MININTERVAL
;
305 lpCaps
->wPeriodMax
= MMSYSTIME_MAXINTERVAL
;
309 /**************************************************************************
310 * timeGetDevCaps [MMSYSTEM.604]
312 MMRESULT16 WINAPI
timeGetDevCaps16(LPTIMECAPS16 lpCaps
, UINT16 wSize
)
314 dprintf_mmtime(stddeb
, "timeGetDevCaps(%p, %u) !\n", lpCaps
, wSize
);
317 lpCaps
->wPeriodMin
= MMSYSTIME_MININTERVAL
;
318 lpCaps
->wPeriodMax
= MMSYSTIME_MAXINTERVAL
;
322 /**************************************************************************
323 * timeBeginPeriod [WINMM.137]
325 MMRESULT32 WINAPI
timeBeginPeriod32(UINT32 wPeriod
)
327 dprintf_mmtime(stddeb
, "timeBeginPeriod32(%u) !\n", wPeriod
);
330 if (wPeriod
< MMSYSTIME_MININTERVAL
|| wPeriod
> MMSYSTIME_MAXINTERVAL
)
331 return TIMERR_NOCANDO
;
334 /**************************************************************************
335 * timeBeginPeriod [MMSYSTEM.605]
337 MMRESULT16 WINAPI
timeBeginPeriod16(UINT16 wPeriod
)
339 dprintf_mmtime(stddeb
, "timeBeginPeriod(%u) !\n", wPeriod
);
342 if (wPeriod
< MMSYSTIME_MININTERVAL
|| wPeriod
> MMSYSTIME_MAXINTERVAL
)
343 return TIMERR_NOCANDO
;
347 /**************************************************************************
348 * timeEndPeriod [WINMM.138]
350 MMRESULT32 WINAPI
timeEndPeriod32(UINT32 wPeriod
)
352 dprintf_mmtime(stddeb
, "timeEndPeriod(%u) !\n", wPeriod
);
353 if (wPeriod
< MMSYSTIME_MININTERVAL
|| wPeriod
> MMSYSTIME_MAXINTERVAL
)
354 return TIMERR_NOCANDO
;
358 /**************************************************************************
359 * timeEndPeriod [MMSYSTEM.606]
361 MMRESULT16 WINAPI
timeEndPeriod16(UINT16 wPeriod
)
363 dprintf_mmtime(stddeb
, "timeEndPeriod(%u) !\n", wPeriod
);
364 if (wPeriod
< MMSYSTIME_MININTERVAL
|| wPeriod
> MMSYSTIME_MAXINTERVAL
)
365 return TIMERR_NOCANDO
;
369 /**************************************************************************
370 * timeGetTime [MMSYSTEM.607][WINMM.141]
372 DWORD WINAPI
timeGetTime()
374 static DWORD lasttick
=0;
377 dprintf_mmtime(stddeb
, "timeGetTime(); !\n");
380 newtick
= GetTickCount();
381 mmSysTimeMS
.u
.ms
+=newtick
-lasttick
; /* FIXME: faked timer */
382 if (newtick
!=lasttick
)
385 dprintf_mmtime(stddeb
, "timeGetTime() // Time = %ld\n",mmSysTimeMS
.u
.ms
);
388 return mmSysTimeMS
.u
.ms
;