Release 970914
[wine.git] / multimedia / time.c
blobcf4905a86517b2314222b4f9784cfbdb21647970
1 /*
2 * MMSYTEM time functions
4 * Copyright 1993 Martin Ayotte
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include "windows.h"
11 #include "win.h"
12 #include "ldt.h"
13 #include "module.h"
14 #include "callback.h"
15 #include "user.h"
16 #include "driver.h"
17 #include "mmsystem.h"
18 #include "stddebug.h"
19 #include "debug.h"
21 static BOOL32 mmTimeStarted = FALSE;
22 static MMTIME mmSysTimeMS;
23 static MMTIME mmSysTimeSMPTE;
25 typedef struct tagTIMERENTRY {
26 WORD wDelay;
27 WORD wResol;
28 FARPROC16 lpFunc;
29 HINSTANCE16 hInstance;
30 DWORD dwUser;
31 WORD wFlags;
32 WORD wTimerID;
33 WORD wCurTime;
34 struct tagTIMERENTRY *Next;
35 } TIMERENTRY, *LPTIMERENTRY;
37 static LPTIMERENTRY lpTimerList = NULL;
40 * FIXME
41 * is this the minimum resolution ?
43 #define MMSYSTIME_MININTERVAL (33)
44 #define MMSYSTIME_MAXINTERVAL (65535)
47 /**************************************************************************
48 * TIME_MMSysTimeCallback
50 static VOID TIME_MMSysTimeCallback( HWND32 hwnd, UINT32 msg,
51 UINT32 id, DWORD dwTime )
53 LPTIMERENTRY lpTimer = lpTimerList;
54 mmSysTimeMS.u.ms += MMSYSTIME_MININTERVAL;
55 mmSysTimeSMPTE.u.smpte.frame++;
56 while (lpTimer != NULL) {
57 lpTimer->wCurTime--;
58 if (lpTimer->wCurTime == 0) {
59 lpTimer->wCurTime = lpTimer->wDelay;
60 if (lpTimer->lpFunc != (FARPROC16) NULL) {
61 dprintf_mmtime(stddeb, "MMSysTimeCallback // before CallBack16 !\n");
62 dprintf_mmtime(stddeb, "MMSysTimeCallback // lpFunc=%p wTimerID=%04X dwUser=%08lX !\n",
63 lpTimer->lpFunc, lpTimer->wTimerID, lpTimer->dwUser);
64 dprintf_mmtime(stddeb, "MMSysTimeCallback // hInstance=%04X !\n", lpTimer->hInstance);
66 /* This is wrong (lpFunc is NULL all the time)
68 lpFunc = MODULE_GetEntryPoint( lpTimer->hInstance,
69 MODULE_GetOrdinal(lpTimer->hInstance,"TimerCallBack" ));
70 dprintf_mmtime(stddeb, "MMSysTimeCallback // lpFunc=%08lx !\n", lpFunc);
74 /* - TimeProc callback that is called here is something strange, under Windows 3.1x it is called
75 * during interrupt time, is allowed to execute very limited number of API calls (like
76 * PostMessage), and must reside in DLL (therefore uses stack of active application). So I
77 * guess current implementation via SetTimer has to be improved upon.
80 CallTimeFuncProc(lpTimer->lpFunc, lpTimer->wTimerID,
81 0, lpTimer->dwUser, 0, 0);
83 dprintf_mmtime(stddeb, "MMSysTimeCallback // after CallBack16 !\n");
84 fflush(stdout);
86 if (lpTimer->wFlags & TIME_ONESHOT)
87 timeKillEvent(lpTimer->wTimerID);
89 lpTimer = lpTimer->Next;
93 /**************************************************************************
94 * StartMMTime [internal]
96 static void StartMMTime()
98 if (!mmTimeStarted) {
99 mmTimeStarted = TRUE;
100 mmSysTimeMS.wType = TIME_MS;
101 mmSysTimeMS.u.ms = 0;
102 mmSysTimeSMPTE.wType = TIME_SMPTE;
103 mmSysTimeSMPTE.u.smpte.hour = 0;
104 mmSysTimeSMPTE.u.smpte.min = 0;
105 mmSysTimeSMPTE.u.smpte.sec = 0;
106 mmSysTimeSMPTE.u.smpte.frame = 0;
107 mmSysTimeSMPTE.u.smpte.fps = 0;
108 mmSysTimeSMPTE.u.smpte.dummy = 0;
109 SetTimer32( 0, 1, MMSYSTIME_MININTERVAL, TIME_MMSysTimeCallback );
113 /**************************************************************************
114 * timeGetSystemTime [MMSYSTEM.601]
116 WORD WINAPI timeGetSystemTime(LPMMTIME lpTime, WORD wSize)
118 dprintf_mmsys(stddeb, "timeGetSystemTime(%p, %u);\n", lpTime, wSize);
119 if (!mmTimeStarted)
120 StartMMTime();
121 lpTime->wType = TIME_MS;
122 lpTime->u.ms = mmSysTimeMS.u.ms;
123 return 0;
126 /**************************************************************************
127 * timeSetEvent [MMSYSTEM.602]
129 WORD WINAPI timeSetEvent(WORD wDelay, WORD wResol, LPTIMECALLBACK lpFunc,
130 DWORD dwUser, WORD wFlags)
132 WORD wNewID = 0;
133 LPTIMERENTRY lpNewTimer;
134 LPTIMERENTRY lpTimer = lpTimerList;
135 dprintf_mmtime(stddeb, "timeSetEvent(%u, %u, %p, %08lX, %04X);\n",
136 wDelay, wResol, lpFunc, dwUser, wFlags);
137 if (!mmTimeStarted)
138 StartMMTime();
139 lpNewTimer = (LPTIMERENTRY)xmalloc(sizeof(TIMERENTRY));
140 if (lpNewTimer == NULL)
141 return 0;
142 while (lpTimer != NULL) {
143 wNewID = MAX(wNewID, lpTimer->wTimerID);
144 lpTimer = lpTimer->Next;
147 lpNewTimer->Next = lpTimerList;
148 lpTimerList = lpNewTimer;
149 lpNewTimer->wTimerID = wNewID + 1;
150 lpNewTimer->wCurTime = wDelay;
151 lpNewTimer->wDelay = wDelay;
152 lpNewTimer->wResol = wResol;
153 lpNewTimer->lpFunc = (FARPROC16) lpFunc;
154 lpNewTimer->hInstance = GetTaskDS();
155 dprintf_mmtime(stddeb, "timeSetEvent // hInstance=%04X !\n", lpNewTimer->hInstance);
156 dprintf_mmtime(stddeb, "timeSetEvent // PTR_SEG_TO_LIN(lpFunc)=%p !\n",
157 PTR_SEG_TO_LIN(lpFunc));
158 lpNewTimer->dwUser = dwUser;
159 lpNewTimer->wFlags = wFlags;
160 return lpNewTimer->wTimerID;
163 /**************************************************************************
164 * timeKillEvent [MMSYSTEM.603]
166 WORD WINAPI timeKillEvent(WORD wID)
168 LPTIMERENTRY xlptimer,*lpTimer = &lpTimerList;
169 while (*lpTimer) {
170 if (wID == (*lpTimer)->wTimerID) {
171 xlptimer = (*lpTimer)->Next;
172 free(*lpTimer);
173 *lpTimer = xlptimer;
174 return TRUE;
176 lpTimer = &((*lpTimer)->Next);
178 return 0;
181 /**************************************************************************
182 * timeGetDevCaps [MMSYSTEM.604]
184 WORD WINAPI timeGetDevCaps(LPTIMECAPS lpCaps, WORD wSize)
186 dprintf_mmtime(stddeb, "timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
187 if (!mmTimeStarted)
188 StartMMTime();
189 lpCaps->wPeriodMin = MMSYSTIME_MININTERVAL;
190 lpCaps->wPeriodMax = MMSYSTIME_MAXINTERVAL;
191 return 0;
194 /**************************************************************************
195 * timeBeginPeriod [MMSYSTEM.605]
197 WORD WINAPI timeBeginPeriod(WORD wPeriod)
199 dprintf_mmtime(stddeb, "timeBeginPeriod(%u) !\n", wPeriod);
200 if (!mmTimeStarted)
201 StartMMTime();
202 if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL)
203 return TIMERR_NOCANDO;
204 return 0;
207 /**************************************************************************
208 * timeEndPeriod [MMSYSTEM.606]
210 WORD WINAPI timeEndPeriod(WORD wPeriod)
212 dprintf_mmtime(stddeb, "timeEndPeriod(%u) !\n", wPeriod);
213 if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL)
214 return TIMERR_NOCANDO;
215 return 0;
218 /**************************************************************************
219 * timeGetTime [MMSYSTEM.607]
221 DWORD WINAPI timeGetTime()
223 dprintf_mmtime(stddeb, "timeGetTime(); !\n");
224 if (!mmTimeStarted)
225 StartMMTime();
226 dprintf_mmtime(stddeb, "timeGetTime() // Time = %ld\n",mmSysTimeMS.u.ms);
227 return mmSysTimeMS.u.ms;