Release 960805
[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                 CallTimeFuncProc(lpTimer->lpFunc, lpTimer->wTimerID, 
76                                     0, lpTimer->dwUser, 0, 0);
77
78                 dprintf_mmtime(stddeb, "MMSysTimeCallback // after CallBack16 !\n");
79                 fflush(stdout);
80             }
81             if (lpTimer->wFlags & TIME_ONESHOT)
82                 timeKillEvent(lpTimer->wTimerID);
83         }
84         lpTimer = lpTimer->Next;
85     }
86 }
87
88 /**************************************************************************
89  *                              StartMMTime                     [internal]
90  */
91 void StartMMTime()
92 {
93     if (!mmTimeStarted) {
94         mmTimeStarted = TRUE;
95         mmSysTimeMS.wType = TIME_MS;
96         mmSysTimeMS.u.ms = 0;
97         mmSysTimeSMPTE.wType = TIME_SMPTE;
98         mmSysTimeSMPTE.u.smpte.hour = 0;
99         mmSysTimeSMPTE.u.smpte.min = 0;
100         mmSysTimeSMPTE.u.smpte.sec = 0;
101         mmSysTimeSMPTE.u.smpte.frame = 0;
102         mmSysTimeSMPTE.u.smpte.fps = 0;
103         mmSysTimeSMPTE.u.smpte.dummy = 0;
104         SetTimer32( 0, 1, 33, TIME_MMSysTimeCallback );
105     }
106 }
107
108 /**************************************************************************
109  *                              timeGetSystemTime       [MMSYSTEM.601]
110  */
111 WORD timeGetSystemTime(LPMMTIME lpTime, WORD wSize)
112 {
113     dprintf_mmsys(stddeb, "timeGetSystemTime(%p, %u);\n", lpTime, wSize);
114     if (!mmTimeStarted)
115         StartMMTime();
116     return 0;
117 }
118
119 /**************************************************************************
120  *                              timeSetEvent            [MMSYSTEM.602]
121  */
122 WORD timeSetEvent(WORD wDelay, WORD wResol, LPTIMECALLBACK lpFunc,
123                   DWORD dwUser, WORD wFlags)
124 {
125     WORD wNewID = 0;
126     LPTIMERENTRY lpNewTimer;
127     LPTIMERENTRY lpTimer = lpTimerList;
128     dprintf_mmtime(stddeb, "timeSetEvent(%u, %u, %p, %08lX, %04X);\n",
129                   wDelay, wResol, lpFunc, dwUser, wFlags);
130     if (!mmTimeStarted)
131         StartMMTime();
132     lpNewTimer = (LPTIMERENTRY) malloc(sizeof(TIMERENTRY));
133     if (lpNewTimer == NULL)
134         return 0;
135     while (lpTimer != NULL) {
136         wNewID = MAX(wNewID, lpTimer->wTimerID);
137         if (lpTimer->Next == NULL)
138             break;
139         lpTimer = lpTimer->Next;
140     }
141     if (lpTimerList == NULL) {
142         lpTimerList = lpNewTimer;
143         lpNewTimer->Prev = NULL;
144     } else {
145         lpTimer->Next = lpNewTimer;
146         lpNewTimer->Prev = lpTimer;
147     }
148     lpNewTimer->Next = NULL;
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;
161 }
162
163 /**************************************************************************
164  *                              timeKillEvent           [MMSYSTEM.603]
165  */
166 WORD timeKillEvent(WORD wID)
167 {
168     LPTIMERENTRY lpTimer = lpTimerList;
169     while (lpTimer != NULL) {
170         if (wID == lpTimer->wTimerID) {
171             if (lpTimer->Prev != NULL)
172                 lpTimer->Prev->Next = lpTimer->Next;
173             if (lpTimer->Next != NULL)
174                 lpTimer->Next->Prev = lpTimer->Prev;
175             free(lpTimer);
176             if (lpTimer==lpTimerList)
177                 lpTimerList=NULL;
178             return TRUE;
179         }
180         lpTimer = lpTimer->Next;
181     }
182     return 0;
183 }
184
185 /**************************************************************************
186  *                              timeGetDevCaps          [MMSYSTEM.604]
187  */
188 WORD timeGetDevCaps(LPTIMECAPS lpCaps, WORD wSize)
189 {
190     dprintf_mmsys(stddeb, "timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
191     return 0;
192 }
193
194 /**************************************************************************
195  *                              timeBeginPeriod         [MMSYSTEM.605]
196  */
197 WORD timeBeginPeriod(WORD wPeriod)
198 {
199     dprintf_mmsys(stddeb, "timeBeginPeriod(%u) !\n", wPeriod);
200     if (!mmTimeStarted)
201         StartMMTime();
202     return 0;
203 }
204
205 /**************************************************************************
206  *                              timeEndPeriod           [MMSYSTEM.606]
207  */
208 WORD timeEndPeriod(WORD wPeriod)
209 {
210     dprintf_mmsys(stddeb, "timeEndPeriod(%u) !\n", wPeriod);
211     return 0;
212 }
213
214 /**************************************************************************
215  *                              timeGetTime             [MMSYSTEM.607]
216  */
217 DWORD timeGetTime()
218 {
219     dprintf_mmsys(stddeb, "timeGetTime(); !\n");
220     if (!mmTimeStarted)
221         StartMMTime();
222     return 0;
223 }
224
225 #endif /* WINELIB */