summaryrefslogtreecommitdiffstats
path: root/private/mvdm/wow16/mmsystem/time.c
blob: 5ebcddcd5c6086e3ab6932095f5e0a4ae3fa35e0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
/******************************************************************************

   Copyright (C) Microsoft Corporation 1985-1991. All rights reserved.

   Title:   TIME.C : MMSYSTEM TIMER API

   Version: 1.00

*****************************************************************************/

//
//  ***DANGER WARNING****
//
//  none of these functions in this file need the default data segment
//  so we undefine BUILDDLL, if you write code in this file that needs
//  DS == DGROUP be warned!
//
//  NOTE: most of this code is interupt time enterable, so we don't want
//  it touching DGROUP anyway!
//
#undef BUILDDLL

#include <windows.h>
#include "mmsystem.h"
#include "mmddk.h"
#include "mmsysi.h"
#include "drvr.h"
#include "thunks.h"


#define MIN_RES     1
#define MIN_DELAY   6

//
//  Define moveable code for timer interface.
//
#pragma alloc_text( RARE, timeGetDevCaps )

extern SZCODE  szTimerDrv[];    // see init.c

//
//  Define the init code for this file.
//
#pragma alloc_text( INIT, TimeInit )


/****************************************************************************

    @doc EXTERNAL

    @api UINT | timeGetSystemTime | This function retrieves the system time
    in milliseconds.  The system time is the time elapsed since
    Windows was started.

    @parm LPMMTIME | lpTime | Specifies a far pointer to an <t MMTIME> data
    structure.

    @parm UINT | wSize | Specifies the size of the <t MMTIME> structure.

    @rdesc Returns zero.
    The system time is returned in the <e MMTIME.ms> field of the <t MMTIME>
    structure.

    @comm The time is always returned in milliseconds.

    @xref timeGetTime
****************************************************************************/
UINT WINAPI
timeGetSystemTime(
    LPMMTIME lpTime,
    UINT wSize
    )
{
    //
    // !!!WARNING DS is not setup right!!! see above
    //
    if (wSize < sizeof(MMTIME))
        return TIMERR_STRUCT;

    lpTime->u.ms  = timeGetTime();
    lpTime->wType = TIME_MS;

    return TIMERR_NOERROR;
}


/****************************************************************************

    @doc EXTERNAL

    @api UINT | timeSetEvent | This function sets up a timed callback event.
    The event can be a one-time event or a periodic event.  Once activated,
    the event calls the specified callback function.

    @parm UINT | wDelay | Specifies the event period in milliseconds.
    If the delay is less than the minimum period supported by the timer,
    or greater than the maximum period supported by the timer, the
    function returns an error.

    @parm UINT | wResolution | Specifies the accuracy of the delay in
    milliseconds. The resolution of the timer event increases with
    smaller <p wResolution> values. To reduce system overhead, use
    the maximum <p wResolution> value appropriate for your application.

    @parm LPTIMECALLBACK | lpFunction | Specifies the procedure address of
    a callback function that is called once upon expiration of a one-shot
    event or periodically upon expiration of periodic events.

    @parm DWORD | dwUser | Contains user-supplied callback data.

    @parm UINT | wFlags | Specifies the type of timer event, using one of
    the following flags:

    @flag TIME_ONESHOT | Event occurs once, after <p wPeriod> milliseconds.

    @flag TIME_PERIODIC | Event occurs every <p wPeriod> milliseconds.

    @rdesc Returns an ID code that identifies the timer event. Returns
    NULL if the timer event was not created. The ID code is also passed to
        the callback function.

    @comm Using this function to generate a high-frequency periodic-delay
    event (with a period less than 10 milliseconds) can consume a
        significant portion of the system CPU bandwidth.  Any call to
    <f timeSetEvent> for a periodic-delay timer
    must be paired with a call to <f timeKillEvent>.

    The callback function must reside in a DLL.  You don't have to use
    <f MakeProcInstance> to get a procedure-instance address for the callback
    function.

    @cb void CALLBACK | TimeFunc | <f TimeFunc> is a placeholder for the
    application-supplied function name.  The actual name must be exported by
    including it in the EXPORTS statement of the module-definition file for
    the DLL.

    @parm UINT | wID | The ID of the timer event.  This is the ID returned
       by <f timeSetEvent>.

    @parm UINT | wMsg | Not used.

    @parm DWORD | dwUser | User instance data supplied to the <p dwUser>
    parameter of <f timeSetEvent>.

    @parm DWORD | dw1 | Not used.

    @parm DWORD | dw2 | Not used.

    @comm Because the callback is accessed at interrupt time, it must
    reside in a DLL, and its code segment must be specified as FIXED
    in the module-definition file for the DLL.  Any data that the
    callback accesses must be in a FIXED data segment as well.
    The callback may not make any system calls except for <f PostMessage>,
    <f timeGetSystemTime>, <f timeGetTime>, <f timeSetEvent>,
    <f timeKillEvent>, <f midiOutShortMsg>,
    <f midiOutLongMsg>, and <f OutputDebugStr>.

    @xref timeKillEvent timeBeginPeriod timeEndPeriod

****************************************************************************/
UINT WINAPI
timeSetEvent(
    UINT wDelay,
    UINT wResolution,
    LPTIMECALLBACK lpFunction,
    DWORD dwUser,
    UINT wFlags
    )
{
    //
    // !!!WARNING DS is not setup right!!! see above
    //
    TIMEREVENT timerEvent;

    V_TCALLBACK(lpFunction, MMSYSERR_INVALPARAM);

    //
    // the first time this is called init the stacks
    // !!!this assumes the first caller will not be at interupt time!!
    //
//  if (!(WinFlags & WF_ENHANCED))
//      timeStackInit();

    wDelay = max( MIN_DELAY, wDelay );
    wResolution = max( MIN_RES, wResolution );

    timerEvent.wDelay = wDelay;
    timerEvent.wResolution = wResolution;
    timerEvent.lpFunction = lpFunction;
    timerEvent.dwUser = dwUser;	
    timerEvent.wFlags = wFlags;

    return (UINT)timeMessage( TDD_SETTIMEREVENT, (LPARAM)(LPVOID)&timerEvent,
                              (LPARAM)GetCurrentTask() );
}



/****************************************************************************

    @doc EXTERNAL

    @api UINT | timeGetDevCaps | This function queries the timer device to
    determine its capabilities.

    @parm LPTIMECAPS | lpTimeCaps | Specifies a far pointer to a
        <t TIMECAPS> structure.  This structure is filled with information
        about the capabilities of the timer device.

    @parm UINT | wSize | Specifies the size of the <t TIMECAPS> structure.

    @rdesc Returns zero if successful. Returns TIMERR_NOCANDO if it fails
    to return the timer device capabilities.

****************************************************************************/
UINT WINAPI
timeGetDevCaps(
    LPTIMECAPS lpTimeCaps,
    UINT wSize
    )
{
    //
    // !!!WARNING DS is not setup right!!! see above
    //
    return (UINT)timeMessage( TDD_GETDEVCAPS, (LPARAM)lpTimeCaps,
                              (LPARAM)(DWORD)wSize);
}



/******************************Public*Routine******************************\
*  timeBeginPeriod
*
*  @doc EXTERNAL
*
*  @api WORD | timeBeginPeriod | This function sets the minimum (lowest
*  number of milliseconds) timer resolution that an application or
*  driver is going to use. Call this function immediately before starting
*  to use timer-event services, and call <f timeEndPeriod> immediately
*  after finishing with the timer-event services.
*
*  @parm WORD | wPeriod | Specifies the minimum timer-event resolution
*  that the application or driver will use.
*
*  @rdesc Returns zero if successful. Returns TIMERR_NOCANDO if the specified
*  <p wPeriod> resolution value is out of range.
*
*  @xref timeEndPeriod timeSetEvent
*
*  @comm For each call to <f timeBeginPeriod>, you must call
*  <f timeEndPeriod> with a matching <p wPeriod> value.
*  An application or driver can make multiple calls to <f timeBeginPeriod>,
*  as long as each <f timeBeginPeriod> call is matched with a
*  <f timeEndPeriod> call.
*
*
*
*
* History:
* dd-mm-93 - StephenE - Created
*
\**************************************************************************/
UINT WINAPI
timeBeginPeriod(
    UINT uPeriod
    )
{
    uPeriod = max( MIN_RES, uPeriod );
    return (UINT)timeMessage( TDD_BEGINMINPERIOD, (LPARAM)uPeriod, 0L );
}



/******************************Public*Routine******************************\
*  timeEndPeriod
*
*  @doc EXTERNAL
*
*  @api WORD | timeEndPeriod | This function clears a previously set
*  minimum (lowest number of milliseconds) timer resolution that an
*  application or driver is going to use. Call this function
*  immediately after using timer event services.
*
*  @parm WORD | wPeriod | Specifies the minimum timer-event resolution
*  value specified in the previous call to <f timeBeginPeriod>.
*
*  @rdesc Returns zero if successful. Returns TIMERR_NOCANDO if the specified
*  <p wPeriod> resolution value is out of range.
*
*  @xref timeBeginPeriod timeSetEvent
*
*  @comm For each call to <f timeBeginPeriod>, you must call
*  <f timeEndPeriod> with a matching <p wPeriod> value.
*  An application or driver can make multiple calls to <f timeBeginPeriod>,
*  as long as each <f timeBeginPeriod> call is matched with a
*  <f timeEndPeriod> call.
*
*
*
* History:
* dd-mm-93 - StephenE - Created
*
\**************************************************************************/
UINT WINAPI
timeEndPeriod(
    UINT uPeriod
    )
{
    uPeriod = max( MIN_RES, uPeriod );
    return (UINT)timeMessage( TDD_ENDMINPERIOD, (LPARAM)uPeriod, 0L );
}



/******************************Public*Routine******************************\
*
*  timeKillEvent
*
*  @doc EXTERNAL
*
*  @api WORD | timeKillEvent | This functions destroys a specified timer
*  callback event.
*
*  @parm WORD | wID | Identifies the event to be destroyed.
*
*  @rdesc Returns zero if successful. Returns TIMERR_NOCANDO if the
*  specified timer event does not exist.
*
*  @comm The timer event ID specified by <p wID> must be an ID
*      returned by <f timeSetEvent>.
*
*  @xref  timeSetEvent
*
*
*
* History:
* dd-mm-93 - StephenE - Created
*
\**************************************************************************/
UINT WINAPI
timeKillEvent(
    UINT wID
    )
{
    if ( 0 == wID ) {
        return 0;
    }
    return (UINT)timeMessage( TDD_KILLTIMEREVENT, (LPARAM)wID, 0L );
}


/******************************Public*Routine******************************\
* timeGetTime
*
* @doc EXTERNAL
*
* @api DWORD | timeGetTime | This function retrieves the system time
* in milliseconds.  The system time is the time elapsed since
* Windows was started.
*
* @rdesc The return value is the system time in milliseconds.
*
* @comm The only difference between this function and
*     the <f timeGetSystemTime> function is <f timeGetSystemTime>
*     uses the standard multimedia time structure <t MMTIME> to return
*     the system time.  The <f timeGetTime> function has less overhead than
*     <f timeGetSystemTime>.
*
* @xref timeGetSystemTime
*
*
*
* History:
* dd-mm-93 - StephenE - Created
*
\**************************************************************************/
DWORD WINAPI
timeGetTime(
    void
    )
{
    return timeMessage( TDD_GETSYSTEMTIME, 0L, 0L );
}


/****************************************************************************

    @doc INTERNAL

    @api BOOL | TimeInit | This function initialises the timer services.

    @rdesc The return value is TRUE if the services are initialised, FALSE
        if an error occurs.

    @comm it is not a FATAL error if a timer driver is not installed, this
          routine will allways return TRUE

****************************************************************************/
BOOL NEAR PASCAL TimeInit(void)
{
    OpenDriver(szTimerDrv, NULL, 0L) ;

    return TRUE;
}