Release 970824
[wine] / misc / system.c
1 /*
2  * SYSTEM DLL routines
3  *
4  * Copyright 1996 Alexandre Julliard
5  */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <signal.h>
10 #include <time.h>
11 #include <sys/time.h>
12 #include <sys/timeb.h>
13 #include <sys/types.h>
14 #include <sys/wait.h>
15
16 #include "windows.h"
17 #include "miscemu.h"
18
19 typedef struct
20 {
21     FARPROC16 callback;  /* NULL if not in use */
22     INT32     rate;
23     INT32     ticks;
24 } SYSTEM_TIMER;
25
26 #define NB_SYS_TIMERS   8
27 #define SYS_TIMER_RATE  54925
28
29 static SYSTEM_TIMER SYS_Timers[NB_SYS_TIMERS];
30 static int SYS_NbTimers = 0;
31 static BOOL32 SYS_TimersDisabled = FALSE;
32
33 /***********************************************************************
34  *           SYSTEM_TimerTick
35  */
36 static void SYSTEM_TimerTick(void)
37 {
38     int i;
39
40     for (i = 0; i < NB_SYS_TIMERS; i++)
41     {
42         if (!SYS_Timers[i].callback) continue;
43         if ((SYS_Timers[i].ticks -= SYS_TIMER_RATE) <= 0)
44         {
45             SYS_Timers[i].ticks += SYS_Timers[i].rate;
46             SYS_Timers[i].callback();
47         }
48     }
49 }
50
51
52 /**********************************************************************
53  *           SYSTEM_StartTicks
54  *
55  * Start the system tick timer.
56  */
57 static void SYSTEM_StartTicks(void)
58 {
59     static BOOL32 handler_installed = FALSE;
60
61     if (!handler_installed)
62     {
63         handler_installed = TRUE;
64         SIGNAL_SetHandler( SIGALRM, SYSTEM_TimerTick, 1 );
65     }
66 #ifndef __EMX__ /* FIXME: Time don't work... Use BIOS directly instead */
67     {
68         struct itimerval vt_timer;
69
70         vt_timer.it_interval.tv_sec = 0;
71         vt_timer.it_interval.tv_usec = 54929;
72         vt_timer.it_value = vt_timer.it_interval;
73         setitimer( ITIMER_REAL, &vt_timer, NULL );
74     }
75 #endif
76 }
77
78
79 /**********************************************************************
80  *           SYSTEM_StopTicks
81  *
82  * Stop the system tick timer.
83  */
84 static void SYSTEM_StopTicks(void)
85 {
86 #ifndef __EMX__ /* FIXME: Time don't work... Use BIOS directly instead */
87     struct itimerval vt_timer;
88
89     vt_timer.it_interval.tv_sec = 0;
90     vt_timer.it_interval.tv_usec = 0;
91     vt_timer.it_value = vt_timer.it_interval;
92     setitimer( ITIMER_REAL, &vt_timer, NULL );
93 #endif
94 }
95
96
97 /***********************************************************************
98  *           InquireSystem   (SYSTEM.1)
99  *
100  * Note: the function always takes 2 WORD arguments, contrary to what
101  *       "Undocumented Windows" says.
102   */
103 DWORD WINAPI InquireSystem( WORD code, WORD arg )
104 {
105     WORD drivetype;
106
107     switch(code)
108     {
109     case 0:  /* Get timer resolution */
110         return SYS_TIMER_RATE;
111
112     case 1:  /* Get drive type */
113         drivetype = GetDriveType16( arg );
114         return MAKELONG( drivetype, drivetype );
115
116     case 2:  /* Enable one-drive logic */
117         fprintf( stderr, "InquireSystem(2): set single-drive %d not supported\n", arg );
118         return 0;
119     }
120     fprintf( stderr, "InquireSystem: unknown code %d\n", code );
121     return 0;
122 }
123
124
125 /***********************************************************************
126  *           CreateSystemTimer   (SYSTEM.2)
127  */
128 WORD WINAPI CreateSystemTimer( WORD rate, FARPROC16 callback )
129 {
130     int i;
131
132     for (i = 0; i < NB_SYS_TIMERS; i++)
133         if (!SYS_Timers[i].callback)  /* Found one */
134         {
135             SYS_Timers[i].rate = (UINT32)rate * 1000;
136             if (SYS_Timers[i].rate < SYS_TIMER_RATE)
137                 SYS_Timers[i].rate = SYS_TIMER_RATE;
138             SYS_Timers[i].ticks = SYS_Timers[i].rate;
139             SYS_Timers[i].callback = callback;
140             if ((++SYS_NbTimers == 1) && !SYS_TimersDisabled)
141                 SYSTEM_StartTicks();
142             return i + 1;  /* 0 means error */
143         }
144     return 0;
145 }
146
147
148 /***********************************************************************
149  *           KillSystemTimer   (SYSTEM.3)
150  *
151  * Note: do not confuse this function with USER.182
152  */
153 WORD WINAPI SYSTEM_KillSystemTimer( WORD timer )
154 {
155     if (!timer || (timer > NB_SYS_TIMERS)) return timer;  /* Error */
156     SYS_Timers[timer-1].callback = NULL;
157     if ((!--SYS_NbTimers) && !SYS_TimersDisabled) SYSTEM_StopTicks();
158     return 0;
159 }
160
161
162 /***********************************************************************
163  *           EnableSystemTimers   (SYSTEM.4)
164  */
165 void WINAPI EnableSystemTimers(void)
166 {
167     SYS_TimersDisabled = FALSE;
168     if (SYS_NbTimers) SYSTEM_StartTicks();
169 }
170
171
172 /***********************************************************************
173  *           DisableSystemTimers   (SYSTEM.5)
174  */
175 void WINAPI DisableSystemTimers(void)
176 {
177     SYS_TimersDisabled = TRUE;
178     if (SYS_NbTimers) SYSTEM_StopTicks();
179 }
180
181
182 /***********************************************************************
183  *           SYSTEM_GetTimerProc
184  *
185  * Return the timer proc of a system timer. Used by thunking code.
186  */
187 FARPROC16 SYSTEM_GetTimerProc( WORD timer )
188 {
189     if (!timer || (timer > NB_SYS_TIMERS)) return NULL;
190     return SYS_Timers[timer-1].callback;
191 }