- Minor API files update.
[wine.git] / windows / timer.c
blobc6639769cd40019e8953e21d987ea64092d7eff2
1 /*
2 * Timer functions
4 * Copyright 1993 Alexandre Julliard
5 */
7 #include "windef.h"
8 #include "wingdi.h"
9 #include "wine/winuser16.h"
10 #include "winuser.h"
11 #include "winerror.h"
13 #include "winproc.h"
14 #include "message.h"
15 #include "server.h"
16 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(timer);
21 typedef struct tagTIMER
23 HWND hwnd;
24 HQUEUE16 hq;
25 UINT16 msg; /* WM_TIMER or WM_SYSTIMER */
26 UINT id;
27 UINT timeout;
28 HWINDOWPROC proc;
29 } TIMER;
31 #define NB_TIMERS 34
32 #define NB_RESERVED_TIMERS 2 /* for SetSystemTimer */
34 #define SYS_TIMER_RATE 55 /* min. timer rate in ms (actually 54.925)*/
36 static TIMER TimersArray[NB_TIMERS];
38 static CRITICAL_SECTION csTimer = CRITICAL_SECTION_INIT;
41 /***********************************************************************
42 * TIMER_ClearTimer
44 * Clear and remove a timer.
46 static void TIMER_ClearTimer( TIMER * pTimer )
48 pTimer->hwnd = 0;
49 pTimer->msg = 0;
50 pTimer->id = 0;
51 pTimer->timeout = 0;
52 WINPROC_FreeProc( pTimer->proc, WIN_PROC_TIMER );
56 /***********************************************************************
57 * TIMER_RemoveWindowTimers
59 * Remove all timers for a given window.
61 void TIMER_RemoveWindowTimers( HWND hwnd )
63 int i;
64 TIMER *pTimer;
66 EnterCriticalSection( &csTimer );
68 for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
69 if ((pTimer->hwnd == hwnd) && pTimer->timeout)
70 TIMER_ClearTimer( pTimer );
72 LeaveCriticalSection( &csTimer );
76 /***********************************************************************
77 * TIMER_RemoveQueueTimers
79 * Remove all timers for a given queue.
81 void TIMER_RemoveQueueTimers( HQUEUE16 hqueue )
83 int i;
84 TIMER *pTimer;
86 EnterCriticalSection( &csTimer );
88 for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
89 if ((pTimer->hq == hqueue) && pTimer->timeout)
90 TIMER_ClearTimer( pTimer );
92 LeaveCriticalSection( &csTimer );
96 /***********************************************************************
97 * TIMER_SetTimer
99 static UINT TIMER_SetTimer( HWND hwnd, UINT id, UINT timeout,
100 WNDPROC16 proc, WINDOWPROCTYPE type, BOOL sys )
102 int i;
103 TIMER * pTimer;
104 HWINDOWPROC winproc = 0;
106 if (hwnd && GetWindowThreadProcessId( hwnd, NULL ) != GetCurrentThreadId())
108 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
109 return 0;
112 if (!timeout)
113 { /* timeout==0 is a legal argument UB 990821*/
114 WARN("Timeout== 0 not implemented, using timeout=1\n");
115 timeout=1;
118 EnterCriticalSection( &csTimer );
120 /* Check if there's already a timer with the same hwnd and id */
122 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
123 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
124 (pTimer->timeout != 0))
126 TIMER_ClearTimer( pTimer );
127 break;
130 if ( i == NB_TIMERS )
132 /* Find a free timer */
134 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
135 if (!pTimer->timeout) break;
137 if ( (i >= NB_TIMERS) ||
138 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) )
140 LeaveCriticalSection( &csTimer );
141 return 0;
145 if (!hwnd) id = i + 1;
147 if (proc) WINPROC_SetProc( &winproc, proc, type, WIN_PROC_TIMER );
149 SERVER_START_REQ( set_win_timer )
151 req->win = hwnd;
152 req->msg = sys ? WM_SYSTIMER : WM_TIMER;
153 req->id = id;
154 req->rate = max( timeout, SYS_TIMER_RATE );
155 req->lparam = (unsigned int)winproc;
156 SERVER_CALL();
158 SERVER_END_REQ;
160 /* Add the timer */
162 pTimer->hwnd = hwnd;
163 pTimer->hq = GetFastQueue16();
164 pTimer->msg = sys ? WM_SYSTIMER : WM_TIMER;
165 pTimer->id = id;
166 pTimer->timeout = timeout;
167 pTimer->proc = winproc;
169 TRACE("Timer added: %p, %04x, %04x, %04x, %08lx\n",
170 pTimer, pTimer->hwnd, pTimer->msg, pTimer->id,
171 (DWORD)pTimer->proc );
173 LeaveCriticalSection( &csTimer );
175 if (!id) return TRUE;
176 else return id;
180 /***********************************************************************
181 * TIMER_KillTimer
183 static BOOL TIMER_KillTimer( HWND hwnd, UINT id, BOOL sys )
185 int i;
186 TIMER * pTimer;
188 SERVER_START_REQ( kill_win_timer )
190 req->win = hwnd;
191 req->msg = sys ? WM_SYSTIMER : WM_TIMER;
192 req->id = id;
193 SERVER_CALL();
195 SERVER_END_REQ;
197 EnterCriticalSection( &csTimer );
199 /* Find the timer */
201 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
202 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
203 (pTimer->timeout != 0)) break;
205 if ( (i >= NB_TIMERS) ||
206 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) ||
207 (!sys && (pTimer->msg != WM_TIMER)) ||
208 (sys && (pTimer->msg != WM_SYSTIMER)) )
210 LeaveCriticalSection( &csTimer );
211 return FALSE;
214 /* Delete the timer */
216 TIMER_ClearTimer( pTimer );
218 LeaveCriticalSection( &csTimer );
220 return TRUE;
224 /***********************************************************************
225 * SetTimer (USER.10)
227 UINT16 WINAPI SetTimer16( HWND16 hwnd, UINT16 id, UINT16 timeout,
228 TIMERPROC16 proc )
230 TRACE("%04x %d %d %08lx\n",
231 hwnd, id, timeout, (LONG)proc );
232 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc,
233 WIN_PROC_16, FALSE );
237 /***********************************************************************
238 * SetTimer (USER32.@)
240 UINT WINAPI SetTimer( HWND hwnd, UINT id, UINT timeout,
241 TIMERPROC proc )
243 TRACE("%04x %d %d %08lx\n",
244 hwnd, id, timeout, (LONG)proc );
245 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc,
246 WIN_PROC_32A, FALSE );
250 /***********************************************************************
251 * TIMER_IsTimerValid
253 BOOL TIMER_IsTimerValid( HWND hwnd, UINT id, HWINDOWPROC hProc )
255 int i;
256 TIMER *pTimer;
257 BOOL ret = FALSE;
259 EnterCriticalSection( &csTimer );
261 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
262 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
263 (pTimer->proc == hProc))
265 ret = TRUE;
266 break;
269 LeaveCriticalSection( &csTimer );
270 return ret;
274 /***********************************************************************
275 * SetSystemTimer (USER.11)
277 UINT16 WINAPI SetSystemTimer16( HWND16 hwnd, UINT16 id, UINT16 timeout,
278 TIMERPROC16 proc )
280 TRACE("%04x %d %d %08lx\n",
281 hwnd, id, timeout, (LONG)proc );
282 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc,
283 WIN_PROC_16, TRUE );
287 /***********************************************************************
288 * SetSystemTimer (USER32.@)
290 UINT WINAPI SetSystemTimer( HWND hwnd, UINT id, UINT timeout,
291 TIMERPROC proc )
293 TRACE("%04x %d %d %08lx\n",
294 hwnd, id, timeout, (LONG)proc );
295 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc,
296 WIN_PROC_32A, TRUE );
300 /***********************************************************************
301 * KillTimer (USER.12)
303 BOOL16 WINAPI KillTimer16( HWND16 hwnd, UINT16 id )
305 TRACE("%04x %d\n", hwnd, id );
306 return TIMER_KillTimer( hwnd, id, FALSE );
310 /***********************************************************************
311 * KillTimer (USER32.@)
313 BOOL WINAPI KillTimer( HWND hwnd, UINT id )
315 TRACE("%04x %d\n", hwnd, id );
316 return TIMER_KillTimer( hwnd, id, FALSE );
320 /***********************************************************************
321 * KillSystemTimer (USER.182)
323 BOOL16 WINAPI KillSystemTimer16( HWND16 hwnd, UINT16 id )
325 TRACE("%04x %d\n", hwnd, id );
326 return TIMER_KillTimer( hwnd, id, TRUE );
330 /***********************************************************************
331 * KillSystemTimer (USER32.@)
333 BOOL WINAPI KillSystemTimer( HWND hwnd, UINT id )
335 TRACE("%04x %d\n", hwnd, id );
336 return TIMER_KillTimer( hwnd, id, TRUE );