Release 960728
[wine] / multimedia / time.c
1 /*
2  * MMSYTEM time functions
3  *
4  * Copyright 1993 Martin Ayotte
5  */
6
7 #ifndef WINELIB
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include "windows.h"
13 #include "win.h"
14 #include "ldt.h"
15 #include "module.h"
16 #include "callback.h"
17 #include "user.h"
18 #include "driver.h"
19 #include "mmsystem.h"
20 #include "stddebug.h"
21 #include "debug.h"
22
23 static BOOL mmTimeStarted = FALSE;
24 static MMTIME mmSysTimeMS;
25 static MMTIME mmSysTimeSMPTE;
26
27 typedef struct tagTIMERENTRY {
28     WORD wDelay;
29     WORD wResol;
30     FARPROC16 lpFunc;
31     HINSTANCE hInstance;
32     DWORD dwUser;
33     WORD wFlags;
34     WORD wTimerID;
35     WORD wCurTime;
36     struct tagTIMERENTRY *Next;
37     struct tagTIMERENTRY *Prev;
38 } TIMERENTRY, *LPTIMERENTRY;
39
40 static LPTIMERENTRY lpTimerList = NULL;
41
42 /**************************************************************************
43  *           TIME_MMSysTimeCallback
44  */
45 static VOID TIME_MMSysTimeCallback( HWND32 hwnd, UINT32 msg,
46                                     UINT32 id, DWORD dwTime )
47 {
48     LPTIMERENTRY lpTimer = lpTimerList;
49     mmSysTimeMS.u.ms += 33;
50     mmSysTimeSMPTE.u.smpte.frame++;
51     while (lpTimer != NULL) {
52         lpTimer->wCurTime--;
53         if (lpTimer->wCurTime == 0) {
54             lpTimer->wCurTime = lpTimer->wDelay;
55             if (lpTimer->lpFunc != (FARPROC16) NULL) {
56                 dprintf_mmtime(stddeb, "MMSysTimeCallback // before CallBack16 !\n");
57                 dprintf_mmtime(stddeb, "MMSysTimeCallback // lpFunc=%p wTimerID=%04X dwUser=%08lX !\n",
58                         lpTimer->lpFunc, lpTimer->wTimerID, lpTimer->dwUser);
59                 dprintf_mmtime(stddeb, "MMSysTimeCallback // hInstance=%04X !\n", lpTimer->hInstance);
60
61 /* This is wrong (lpFunc is NULL all the time)
62
63                 lpFunc = MODULE_GetEntryPoint( lpTimer->hInstance,
64                          MODULE_GetOrdinal(lpTimer->hInstance,"TimerCallBack" ));
65                 dprintf_mmtime(stddeb, "MMSysTimeCallback // lpFunc=%08lx !\n", lpFunc);
66 */
67
68
69 /*        - TimeProc callback that is called here is something strange, under Windows 3.1x it is called 
70  *          during interrupt time,  is allowed to execute very limited number of API calls (like
71  *          PostMessage), and must reside in DLL (therefore uses stack of active application). So I 
72  *          guess current implementation via SetTimer has to be improved upon.          
73  */
74
75                 CallTo16_word_wwlll(lpTimer->lpFunc,
76                         lpTimer->hInstance, lpTimer->wTimerID, 
77                         0, lpTimer->dwUser, 0, 0);
78
79                 dprintf_mmtime(stddeb, "MMSysTimeCallback // after CallBack16 !\n");
80                 fflush(stdout);
81             }
82             if (lpTimer->wFlags & TIME_ONESHOT)
83                 timeKillEvent(lpTimer->wTimerID);
84         }
85         lpTimer = lpTimer->Next;
86     }
87 }
88
89 /**************************************************************************
90  *                              StartMMTime                     [internal]
91  */
92 void StartMMTime()
93 {
94     if (!mmTimeStarted) {
95         mmTimeStarted = TRUE;
96         mmSysTimeMS.wType = TIME_MS;
97         mmSysTimeMS.u.ms = 0;
98         mmSysTimeSMPTE.wType = TIME_SMPTE;
99         mmSysTimeSMPTE.u.smpte.hour = 0;
100         mmSysTimeSMPTE.u.smpte.min = 0;
101         mmSysTimeSMPTE.u.smpte.sec = 0;
102         mmSysTimeSMPTE.u.smpte.frame = 0;
103         mmSysTimeSMPTE.u.smpte.fps = 0;
104         mmSysTimeSMPTE.u.smpte.dummy = 0;
105         SetTimer32( 0, 1, 33, TIME_MMSysTimeCallback );
106     }
107 }
108
109 /**************************************************************************
110  *                              timeGetSystemTime       [MMSYSTEM.601]
111  */
112 WORD timeGetSystemTime(LPMMTIME lpTime, WORD wSize)
113 {
114     dprintf_mmsys(stddeb, "timeGetSystemTime(%p, %u);\n", lpTime, wSize);
115     if (!mmTimeStarted)
116         StartMMTime();
117     return 0;
118 }
119
120 /**************************************************************************
121  *                              timeSetEvent            [MMSYSTEM.602]
122  */
123 WORD timeSetEvent(WORD wDelay, WORD wResol, LPTIMECALLBACK lpFunc,
124                   DWORD dwUser, WORD wFlags)
125 {
126     WORD wNewID = 0;
127     LPTIMERENTRY lpNewTimer;
128     LPTIMERENTRY lpTimer = lpTimerList;
129     dprintf_mmtime(stddeb, "timeSetEvent(%u, %u, %p, %08lX, %04X);\n",
130                   wDelay, wResol, lpFunc, dwUser, wFlags);
131     if (!mmTimeStarted)
132         StartMMTime();
133     lpNewTimer = (LPTIMERENTRY) malloc(sizeof(TIMERENTRY));
134     if (lpNewTimer == NULL)
135         return 0;
136     while (lpTimer != NULL) {
137         wNewID = MAX(wNewID, lpTimer->wTimerID);
138         if (lpTimer->Next == NULL)
139             break;
140         lpTimer = lpTimer->Next;
141     }
142     if (lpTimerList == NULL) {
143         lpTimerList = lpNewTimer;
144         lpNewTimer->Prev = NULL;
145     } else {
146         lpTimer->Next = lpNewTimer;
147         lpNewTimer->Prev = lpTimer;
148     }
149     lpNewTimer->Next = NULL;
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;
162 }
163
164 /**************************************************************************
165  *                              timeKillEvent           [MMSYSTEM.603]
166  */
167 WORD timeKillEvent(WORD wID)
168 {
169     LPTIMERENTRY lpTimer = lpTimerList;
170     while (lpTimer != NULL) {
171         if (wID == lpTimer->wTimerID) {
172             if (lpTimer->Prev != NULL)
173                 lpTimer->Prev->Next = lpTimer->Next;
174             if (lpTimer->Next != NULL)
175                 lpTimer->Next->Prev = lpTimer->Prev;
176             free(lpTimer);
177             if (lpTimer==lpTimerList)
178                 lpTimerList=NULL;
179             return TRUE;
180         }
181         lpTimer = lpTimer->Next;
182     }
183     return 0;
184 }
185
186 /**************************************************************************
187  *                              timeGetDevCaps          [MMSYSTEM.604]
188  */
189 WORD timeGetDevCaps(LPTIMECAPS lpCaps, WORD wSize)
190 {
191     dprintf_mmsys(stddeb, "timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
192     return 0;
193 }
194
195 /**************************************************************************
196  *                              timeBeginPeriod         [MMSYSTEM.605]
197  */
198 WORD timeBeginPeriod(WORD wPeriod)
199 {
200     dprintf_mmsys(stddeb, "timeBeginPeriod(%u) !\n", wPeriod);
201     if (!mmTimeStarted)
202         StartMMTime();
203     return 0;
204 }
205
206 /**************************************************************************
207  *                              timeEndPeriod           [MMSYSTEM.606]
208  */
209 WORD timeEndPeriod(WORD wPeriod)
210 {
211     dprintf_mmsys(stddeb, "timeEndPeriod(%u) !\n", wPeriod);
212     return 0;
213 }
214
215 /**************************************************************************
216  *                              timeGetTime             [MMSYSTEM.607]
217  */
218 DWORD timeGetTime()
219 {
220     dprintf_mmsys(stddeb, "timeGetTime(); !\n");
221     if (!mmTimeStarted)
222         StartMMTime();
223     return 0;
224 }
225
226 #endif /* WINELIB */