Release 971012
[wine.git] / multimedia / time.c
bloba9c7976221c98ced4c3431d10a92a657491bfee8
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"
20 #include "xmalloc.h"
22 static BOOL32 mmTimeStarted = FALSE;
23 static MMTIME mmSysTimeMS;
24 static MMTIME mmSysTimeSMPTE;
26 typedef struct tagTIMERENTRY {
27 WORD wDelay;
28 WORD wResol;
29 FARPROC16 lpFunc;
30 HINSTANCE16 hInstance;
31 DWORD dwUser;
32 WORD wFlags;
33 WORD wTimerID;
34 WORD wCurTime;
35 struct tagTIMERENTRY *Next;
36 } TIMERENTRY, *LPTIMERENTRY;
38 static LPTIMERENTRY lpTimerList = NULL;
41 * FIXME
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) {
58 lpTimer->wCurTime--;
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");
85 fflush(stdout);
87 if (lpTimer->wFlags & TIME_ONESHOT)
88 timeKillEvent(lpTimer->wTimerID);
90 lpTimer = lpTimer->Next;
94 /**************************************************************************
95 * StartMMTime [internal]
97 static void StartMMTime()
99 if (!mmTimeStarted) {
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);
120 if (!mmTimeStarted)
121 StartMMTime();
122 lpTime->wType = TIME_MS;
123 lpTime->u.ms = mmSysTimeMS.u.ms;
124 return 0;
127 /**************************************************************************
128 * timeSetEvent [MMSYSTEM.602]
130 WORD WINAPI timeSetEvent(WORD wDelay, WORD wResol, LPTIMECALLBACK lpFunc,
131 DWORD dwUser, WORD wFlags)
133 WORD wNewID = 0;
134 LPTIMERENTRY lpNewTimer;
135 LPTIMERENTRY lpTimer = lpTimerList;
136 dprintf_mmtime(stddeb, "timeSetEvent(%u, %u, %p, %08lX, %04X);\n",
137 wDelay, wResol, lpFunc, dwUser, wFlags);
138 if (!mmTimeStarted)
139 StartMMTime();
140 lpNewTimer = (LPTIMERENTRY)xmalloc(sizeof(TIMERENTRY));
141 if (lpNewTimer == NULL)
142 return 0;
143 while (lpTimer != NULL) {
144 wNewID = MAX(wNewID, lpTimer->wTimerID);
145 lpTimer = lpTimer->Next;
148 lpNewTimer->Next = lpTimerList;
149 lpTimerList = lpNewTimer;
150 lpNewTimer->wTimerID = wNewID + 1;
151 lpNewTimer->wCurTime = wDelay;
152 lpNewTimer->wDelay = wDelay;
153 lpNewTimer->wResol = wResol;
154 lpNewTimer->lpFunc = (FARPROC16) lpFunc;
155 lpNewTimer->hInstance = GetTaskDS();
156 dprintf_mmtime(stddeb, "timeSetEvent // hInstance=%04X !\n", lpNewTimer->hInstance);
157 dprintf_mmtime(stddeb, "timeSetEvent // PTR_SEG_TO_LIN(lpFunc)=%p !\n",
158 PTR_SEG_TO_LIN(lpFunc));
159 lpNewTimer->dwUser = dwUser;
160 lpNewTimer->wFlags = wFlags;
161 return lpNewTimer->wTimerID;
164 /**************************************************************************
165 * timeKillEvent [MMSYSTEM.603]
167 WORD WINAPI timeKillEvent(WORD wID)
169 LPTIMERENTRY xlptimer,*lpTimer = &lpTimerList;
170 while (*lpTimer) {
171 if (wID == (*lpTimer)->wTimerID) {
172 xlptimer = (*lpTimer)->Next;
173 free(*lpTimer);
174 *lpTimer = xlptimer;
175 return TRUE;
177 lpTimer = &((*lpTimer)->Next);
179 return 0;
182 /**************************************************************************
183 * timeGetDevCaps [MMSYSTEM.604]
185 WORD WINAPI timeGetDevCaps(LPTIMECAPS lpCaps, WORD wSize)
187 dprintf_mmtime(stddeb, "timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
188 if (!mmTimeStarted)
189 StartMMTime();
190 lpCaps->wPeriodMin = MMSYSTIME_MININTERVAL;
191 lpCaps->wPeriodMax = MMSYSTIME_MAXINTERVAL;
192 return 0;
195 /**************************************************************************
196 * timeBeginPeriod [MMSYSTEM.605]
198 WORD WINAPI timeBeginPeriod(WORD wPeriod)
200 dprintf_mmtime(stddeb, "timeBeginPeriod(%u) !\n", wPeriod);
201 if (!mmTimeStarted)
202 StartMMTime();
203 if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL)
204 return TIMERR_NOCANDO;
205 return 0;
208 /**************************************************************************
209 * timeEndPeriod [MMSYSTEM.606]
211 WORD WINAPI timeEndPeriod(WORD wPeriod)
213 dprintf_mmtime(stddeb, "timeEndPeriod(%u) !\n", wPeriod);
214 if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL)
215 return TIMERR_NOCANDO;
216 return 0;
219 /**************************************************************************
220 * timeGetTime [MMSYSTEM.607]
222 DWORD WINAPI timeGetTime()
224 dprintf_mmtime(stddeb, "timeGetTime(); !\n");
225 if (!mmTimeStarted)
226 StartMMTime();
227 dprintf_mmtime(stddeb, "timeGetTime() // Time = %ld\n",mmSysTimeMS.u.ms);
228 return mmSysTimeMS.u.ms;