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