2 * MMSYTEM time functions
4 * Copyright 1993 Martin Ayotte
21 static BOOL32 mmTimeStarted = FALSE;
22 static MMTIME mmSysTimeMS;
23 static MMTIME mmSysTimeSMPTE;
25 typedef struct tagTIMERENTRY {
29 HINSTANCE16 hInstance;
34 struct tagTIMERENTRY *Next;
35 struct tagTIMERENTRY *Prev;
36 } TIMERENTRY, *LPTIMERENTRY;
38 static LPTIMERENTRY lpTimerList = NULL;
42 * is this the minimum resolution ?
44 #define MMSYSTIME_MININTERVAL (33)
45 #define MMSYSTIME_MAXINTERVAL (65535)
48 /**************************************************************************
49 * TIME_MMSysTimeCallback
51 static VOID TIME_MMSysTimeCallback( HWND32 hwnd, UINT32 msg,
52 UINT32 id, DWORD dwTime )
54 LPTIMERENTRY lpTimer = lpTimerList;
55 mmSysTimeMS.u.ms += MMSYSTIME_MININTERVAL;
56 mmSysTimeSMPTE.u.smpte.frame++;
57 while (lpTimer != NULL) {
59 if (lpTimer->wCurTime == 0) {
60 lpTimer->wCurTime = lpTimer->wDelay;
61 if (lpTimer->lpFunc != (FARPROC16) NULL) {
62 dprintf_mmtime(stddeb, "MMSysTimeCallback // before CallBack16 !\n");
63 dprintf_mmtime(stddeb, "MMSysTimeCallback // lpFunc=%p wTimerID=%04X dwUser=%08lX !\n",
64 lpTimer->lpFunc, lpTimer->wTimerID, lpTimer->dwUser);
65 dprintf_mmtime(stddeb, "MMSysTimeCallback // hInstance=%04X !\n", lpTimer->hInstance);
67 /* This is wrong (lpFunc is NULL all the time)
69 lpFunc = MODULE_GetEntryPoint( lpTimer->hInstance,
70 MODULE_GetOrdinal(lpTimer->hInstance,"TimerCallBack" ));
71 dprintf_mmtime(stddeb, "MMSysTimeCallback // lpFunc=%08lx !\n", lpFunc);
75 /* - TimeProc callback that is called here is something strange, under Windows 3.1x it is called
76 * during interrupt time, is allowed to execute very limited number of API calls (like
77 * PostMessage), and must reside in DLL (therefore uses stack of active application). So I
78 * guess current implementation via SetTimer has to be improved upon.
81 CallTimeFuncProc(lpTimer->lpFunc, lpTimer->wTimerID,
82 0, lpTimer->dwUser, 0, 0);
84 dprintf_mmtime(stddeb, "MMSysTimeCallback // after CallBack16 !\n");
87 if (lpTimer->wFlags & TIME_ONESHOT)
88 timeKillEvent(lpTimer->wTimerID);
90 lpTimer = lpTimer->Next;
94 /**************************************************************************
95 * StartMMTime [internal]
97 static void StartMMTime()
100 mmTimeStarted = TRUE;
101 mmSysTimeMS.wType = TIME_MS;
102 mmSysTimeMS.u.ms = 0;
103 mmSysTimeSMPTE.wType = TIME_SMPTE;
104 mmSysTimeSMPTE.u.smpte.hour = 0;
105 mmSysTimeSMPTE.u.smpte.min = 0;
106 mmSysTimeSMPTE.u.smpte.sec = 0;
107 mmSysTimeSMPTE.u.smpte.frame = 0;
108 mmSysTimeSMPTE.u.smpte.fps = 0;
109 mmSysTimeSMPTE.u.smpte.dummy = 0;
110 SetTimer32( 0, 1, MMSYSTIME_MININTERVAL, TIME_MMSysTimeCallback );
114 /**************************************************************************
115 * timeGetSystemTime [MMSYSTEM.601]
117 WORD WINAPI timeGetSystemTime(LPMMTIME lpTime, WORD wSize)
119 dprintf_mmsys(stddeb, "timeGetSystemTime(%p, %u);\n", lpTime, wSize);
122 lpTime->wType = TIME_MS;
123 lpTime->u.ms = mmSysTimeMS.u.ms;
127 /**************************************************************************
128 * timeSetEvent [MMSYSTEM.602]
130 WORD WINAPI timeSetEvent(WORD wDelay, WORD wResol, LPTIMECALLBACK lpFunc,
131 DWORD dwUser, WORD wFlags)
134 LPTIMERENTRY lpNewTimer;
135 LPTIMERENTRY lpTimer = lpTimerList;
136 dprintf_mmtime(stddeb, "timeSetEvent(%u, %u, %p, %08lX, %04X);\n",
137 wDelay, wResol, lpFunc, dwUser, wFlags);
140 lpNewTimer = (LPTIMERENTRY) malloc(sizeof(TIMERENTRY));
141 if (lpNewTimer == NULL)
143 while (lpTimer != NULL) {
144 wNewID = MAX(wNewID, lpTimer->wTimerID);
145 if (lpTimer->Next == NULL)
147 lpTimer = lpTimer->Next;
149 if (lpTimerList == NULL) {
150 lpTimerList = lpNewTimer;
151 lpNewTimer->Prev = NULL;
153 lpTimer->Next = lpNewTimer;
154 lpNewTimer->Prev = lpTimer;
156 lpNewTimer->Next = NULL;
157 lpNewTimer->wTimerID = wNewID + 1;
158 lpNewTimer->wCurTime = wDelay;
159 lpNewTimer->wDelay = wDelay;
160 lpNewTimer->wResol = wResol;
161 lpNewTimer->lpFunc = (FARPROC16) lpFunc;
162 lpNewTimer->hInstance = GetTaskDS();
163 dprintf_mmtime(stddeb, "timeSetEvent // hInstance=%04X !\n", lpNewTimer->hInstance);
164 dprintf_mmtime(stddeb, "timeSetEvent // PTR_SEG_TO_LIN(lpFunc)=%p !\n",
165 PTR_SEG_TO_LIN(lpFunc));
166 lpNewTimer->dwUser = dwUser;
167 lpNewTimer->wFlags = wFlags;
168 return lpNewTimer->wTimerID;
171 /**************************************************************************
172 * timeKillEvent [MMSYSTEM.603]
174 WORD WINAPI timeKillEvent(WORD wID)
176 LPTIMERENTRY lpTimer = lpTimerList;
177 while (lpTimer != NULL) {
178 if (wID == lpTimer->wTimerID) {
179 if (lpTimer->Prev != NULL)
180 lpTimer->Prev->Next = lpTimer->Next;
181 if (lpTimer->Next != NULL)
182 lpTimer->Next->Prev = lpTimer->Prev;
184 if (lpTimer==lpTimerList)
188 lpTimer = lpTimer->Next;
193 /**************************************************************************
194 * timeGetDevCaps [MMSYSTEM.604]
196 WORD WINAPI timeGetDevCaps(LPTIMECAPS lpCaps, WORD wSize)
198 dprintf_mmtime(stddeb, "timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
201 lpCaps->wPeriodMin = MMSYSTIME_MININTERVAL;
202 lpCaps->wPeriodMax = MMSYSTIME_MAXINTERVAL;
206 /**************************************************************************
207 * timeBeginPeriod [MMSYSTEM.605]
209 WORD WINAPI timeBeginPeriod(WORD wPeriod)
211 dprintf_mmtime(stddeb, "timeBeginPeriod(%u) !\n", wPeriod);
214 if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL)
215 return TIMERR_NOCANDO;
219 /**************************************************************************
220 * timeEndPeriod [MMSYSTEM.606]
222 WORD WINAPI timeEndPeriod(WORD wPeriod)
224 dprintf_mmtime(stddeb, "timeEndPeriod(%u) !\n", wPeriod);
225 if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL)
226 return TIMERR_NOCANDO;
230 /**************************************************************************
231 * timeGetTime [MMSYSTEM.607]
233 DWORD WINAPI timeGetTime()
235 dprintf_mmtime(stddeb, "timeGetTime(); !\n");
238 dprintf_mmtime(stddeb, "timeGetTime() // Time = %ld\n",mmSysTimeMS.u.ms);
239 return mmSysTimeMS.u.ms;