Use services thread instead of timer signals.
[wine] / misc / system.c
1 /*
2  * SYSTEM DLL routines
3  *
4  * Copyright 1996 Alexandre Julliard
5  */
6
7 #include "wine/winbase16.h"
8 #include "wine/winuser16.h"
9 #include "services.h"
10 #include "debug.h"
11
12 typedef struct
13 {
14     SYSTEMTIMERPROC callback;  /* NULL if not in use */
15     INT     rate;
16     INT     ticks;
17 } SYSTEM_TIMER;
18
19 #define NB_SYS_TIMERS   8
20 #define SYS_TIMER_RATE  54925
21
22 static SYSTEM_TIMER SYS_Timers[NB_SYS_TIMERS];
23 static int SYS_NbTimers = 0;
24 static HANDLE SYS_Service = INVALID_HANDLE_VALUE;
25
26
27 /***********************************************************************
28  *           SYSTEM_TimerTick
29  */
30 static void CALLBACK SYSTEM_TimerTick( ULONG_PTR arg )
31 {
32     int i;
33
34     for (i = 0; i < NB_SYS_TIMERS; i++)
35     {
36         if (!SYS_Timers[i].callback) continue;
37         if ((SYS_Timers[i].ticks -= SYS_TIMER_RATE) <= 0)
38         {
39             SYS_Timers[i].ticks += SYS_Timers[i].rate;
40             SYS_Timers[i].callback( i+1 );
41         }
42     }
43 }
44
45 /**********************************************************************
46  *           SYSTEM_StartTicks
47  *
48  * Start the system tick timer.
49  */
50 static void SYSTEM_StartTicks(void)
51 {
52     if ( SYS_Service == INVALID_HANDLE_VALUE )
53         SYS_Service = SERVICE_AddTimer( SYS_TIMER_RATE, SYSTEM_TimerTick, 0L );
54 }
55
56
57 /**********************************************************************
58  *           SYSTEM_StopTicks
59  *
60  * Stop the system tick timer.
61  */
62 static void SYSTEM_StopTicks(void)
63 {
64     if ( SYS_Service != INVALID_HANDLE_VALUE )
65     {
66         SERVICE_Delete( SYS_Service );
67         SYS_Service = INVALID_HANDLE_VALUE;
68     }
69 }
70
71
72 /***********************************************************************
73  *           InquireSystem   (SYSTEM.1)
74  *
75  * Note: the function always takes 2 WORD arguments, contrary to what
76  *       "Undocumented Windows" says.
77   */
78 DWORD WINAPI InquireSystem16( WORD code, WORD arg )
79 {
80     WORD drivetype;
81
82     switch(code)
83     {
84     case 0:  /* Get timer resolution */
85         return SYS_TIMER_RATE;
86
87     case 1:  /* Get drive type */
88         drivetype = GetDriveType16( arg );
89         return MAKELONG( drivetype, drivetype );
90
91     case 2:  /* Enable one-drive logic */
92         FIXME(system, "Case %d: set single-drive %d not supported\n", code, arg );
93         return 0;
94     }
95     WARN(system, "Unknown code %d\n", code );
96     return 0;
97 }
98
99
100 /***********************************************************************
101  *           CreateSystemTimer   (SYSTEM.2)
102  */
103 WORD WINAPI CreateSystemTimer( WORD rate, SYSTEMTIMERPROC callback )
104 {
105     int i;
106     for (i = 0; i < NB_SYS_TIMERS; i++)
107         if (!SYS_Timers[i].callback)  /* Found one */
108         {
109             SYS_Timers[i].rate = (UINT)rate * 1000;
110             if (SYS_Timers[i].rate < SYS_TIMER_RATE)
111                 SYS_Timers[i].rate = SYS_TIMER_RATE;
112             SYS_Timers[i].ticks = SYS_Timers[i].rate;
113             SYS_Timers[i].callback = callback;
114             if (++SYS_NbTimers == 1) SYSTEM_StartTicks();
115             return i + 1;  /* 0 means error */
116         }
117     return 0;
118 }
119
120
121 /***********************************************************************
122  *           KillSystemTimer   (SYSTEM.3)
123  *
124  * Note: do not confuse this function with USER.182
125  */
126 WORD WINAPI SYSTEM_KillSystemTimer( WORD timer )
127 {
128     if (!timer || (timer > NB_SYS_TIMERS)) return timer;  /* Error */
129     SYS_Timers[timer-1].callback = NULL;
130     if (!--SYS_NbTimers) SYSTEM_StopTicks();
131     return 0;
132 }
133
134
135 /***********************************************************************
136  *           EnableSystemTimers   (SYSTEM.4)
137  */
138 void WINAPI EnableSystemTimers16(void)
139 {
140     if ( SYS_Service != INVALID_HANDLE_VALUE )
141         SERVICE_Enable( SYS_Service );
142 }
143
144
145 /***********************************************************************
146  *           DisableSystemTimers   (SYSTEM.5)
147  */
148 void WINAPI DisableSystemTimers16(void)
149 {
150     if ( SYS_Service != INVALID_HANDLE_VALUE )
151         SERVICE_Disable( SYS_Service );
152 }