Fixed header dependencies to be fully compatible with the Windows
[wine/multimedia.git] / windows / timer.c
blobf127021a181d562ad528903bd5337d396817dcdd
1 /*
2 * Timer functions
4 * Copyright 1993 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 #include "wine/winuser16.h"
27 #include "winuser.h"
28 #include "winerror.h"
30 #include "winproc.h"
31 #include "message.h"
32 #include "win.h"
33 #include "wine/server.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(timer);
39 typedef struct tagTIMER
41 HWND hwnd;
42 DWORD thread;
43 UINT msg; /* WM_TIMER or WM_SYSTIMER */
44 UINT id;
45 UINT timeout;
46 WNDPROC proc;
47 } TIMER;
49 #define NB_TIMERS 34
50 #define NB_RESERVED_TIMERS 2 /* for SetSystemTimer */
52 #define SYS_TIMER_RATE 55 /* min. timer rate in ms (actually 54.925)*/
54 static TIMER TimersArray[NB_TIMERS];
56 static CRITICAL_SECTION csTimer;
57 static CRITICAL_SECTION_DEBUG critsect_debug =
59 0, 0, &csTimer,
60 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
61 0, 0, { 0, (DWORD)(__FILE__ ": csTimer") }
63 static CRITICAL_SECTION csTimer = { &critsect_debug, -1, 0, 0, 0, 0 };
66 /***********************************************************************
67 * TIMER_ClearTimer
69 * Clear and remove a timer.
71 static void TIMER_ClearTimer( TIMER * pTimer )
73 pTimer->hwnd = 0;
74 pTimer->msg = 0;
75 pTimer->id = 0;
76 pTimer->timeout = 0;
77 WINPROC_FreeProc( pTimer->proc, WIN_PROC_TIMER );
81 /***********************************************************************
82 * TIMER_RemoveWindowTimers
84 * Remove all timers for a given window.
86 void TIMER_RemoveWindowTimers( HWND hwnd )
88 int i;
89 TIMER *pTimer;
91 EnterCriticalSection( &csTimer );
93 for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
94 if ((pTimer->hwnd == hwnd) && pTimer->timeout)
95 TIMER_ClearTimer( pTimer );
97 LeaveCriticalSection( &csTimer );
101 /***********************************************************************
102 * TIMER_RemoveThreadTimers
104 * Remove all timers for the current thread.
106 void TIMER_RemoveThreadTimers(void)
108 int i;
109 TIMER *pTimer;
111 EnterCriticalSection( &csTimer );
113 for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
114 if ((pTimer->thread == GetCurrentThreadId()) && pTimer->timeout)
115 TIMER_ClearTimer( pTimer );
117 LeaveCriticalSection( &csTimer );
121 /***********************************************************************
122 * TIMER_SetTimer
124 static UINT_PTR TIMER_SetTimer( HWND hwnd, UINT_PTR id, UINT timeout,
125 WNDPROC proc, WINDOWPROCTYPE type, BOOL sys )
127 int i;
128 TIMER * pTimer;
129 WNDPROC winproc = 0;
131 if (hwnd && !(hwnd = WIN_IsCurrentThread( hwnd )))
133 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
134 return 0;
137 if (!timeout)
138 { /* timeout==0 is a legal argument UB 990821*/
139 WARN("Timeout== 0 not implemented, using timeout=1\n");
140 timeout=1;
143 EnterCriticalSection( &csTimer );
145 /* Check if there's already a timer with the same hwnd and id */
147 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
148 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
149 (pTimer->timeout != 0))
151 TIMER_ClearTimer( pTimer );
152 break;
155 if ( i == NB_TIMERS )
157 /* Find a free timer */
159 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
160 if (!pTimer->timeout) break;
162 if ( (i >= NB_TIMERS) ||
163 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) )
165 LeaveCriticalSection( &csTimer );
166 return 0;
170 if (!hwnd) id = i + 1;
172 if (proc) WINPROC_SetProc( &winproc, proc, type, WIN_PROC_TIMER );
174 SERVER_START_REQ( set_win_timer )
176 req->win = hwnd;
177 req->msg = sys ? WM_SYSTIMER : WM_TIMER;
178 req->id = id;
179 req->rate = max( timeout, SYS_TIMER_RATE );
180 req->lparam = (unsigned int)winproc;
181 wine_server_call( req );
183 SERVER_END_REQ;
185 /* Add the timer */
187 pTimer->hwnd = hwnd;
188 pTimer->thread = GetCurrentThreadId();
189 pTimer->msg = sys ? WM_SYSTIMER : WM_TIMER;
190 pTimer->id = id;
191 pTimer->timeout = timeout;
192 pTimer->proc = winproc;
194 TRACE("Timer added: %p, %p, %04x, %04x, %p\n",
195 pTimer, pTimer->hwnd, pTimer->msg, pTimer->id, pTimer->proc );
197 LeaveCriticalSection( &csTimer );
199 if (!id) return TRUE;
200 else return id;
204 /***********************************************************************
205 * TIMER_KillTimer
207 static BOOL TIMER_KillTimer( HWND hwnd, UINT_PTR id, BOOL sys )
209 int i;
210 TIMER * pTimer;
212 SERVER_START_REQ( kill_win_timer )
214 req->win = hwnd;
215 req->msg = sys ? WM_SYSTIMER : WM_TIMER;
216 req->id = id;
217 wine_server_call( req );
219 SERVER_END_REQ;
221 EnterCriticalSection( &csTimer );
223 /* Find the timer */
225 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
226 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
227 (pTimer->timeout != 0)) break;
229 if ( (i >= NB_TIMERS) ||
230 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) ||
231 (!sys && (pTimer->msg != WM_TIMER)) ||
232 (sys && (pTimer->msg != WM_SYSTIMER)) )
234 LeaveCriticalSection( &csTimer );
235 return FALSE;
238 /* Delete the timer */
240 TIMER_ClearTimer( pTimer );
242 LeaveCriticalSection( &csTimer );
244 return TRUE;
248 /***********************************************************************
249 * SetTimer (USER.10)
251 UINT16 WINAPI SetTimer16( HWND16 hwnd, UINT16 id, UINT16 timeout,
252 TIMERPROC16 proc )
254 TRACE("%04x %d %d %08lx\n",
255 hwnd, id, timeout, (LONG)proc );
256 return TIMER_SetTimer( WIN_Handle32(hwnd), id, timeout, (WNDPROC)proc,
257 WIN_PROC_16, FALSE );
261 /***********************************************************************
262 * SetTimer (USER32.@)
264 UINT_PTR WINAPI SetTimer( HWND hwnd, UINT_PTR id, UINT timeout,
265 TIMERPROC proc )
267 TRACE("%p %d %d %p\n", hwnd, id, timeout, proc );
268 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC)proc, WIN_PROC_32A, FALSE );
272 /***********************************************************************
273 * TIMER_IsTimerValid
275 BOOL TIMER_IsTimerValid( HWND hwnd, UINT_PTR id, WNDPROC proc )
277 int i;
278 TIMER *pTimer;
279 BOOL ret = FALSE;
281 hwnd = WIN_GetFullHandle( hwnd );
282 EnterCriticalSection( &csTimer );
284 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
285 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) && (pTimer->proc == proc))
287 ret = TRUE;
288 break;
291 LeaveCriticalSection( &csTimer );
292 return ret;
296 /***********************************************************************
297 * SetSystemTimer (USER.11)
299 UINT16 WINAPI SetSystemTimer16( HWND16 hwnd, UINT16 id, UINT16 timeout,
300 TIMERPROC16 proc )
302 TRACE("%04x %d %d %08lx\n",
303 hwnd, id, timeout, (LONG)proc );
304 return TIMER_SetTimer( WIN_Handle32(hwnd), id, timeout, (WNDPROC)proc, WIN_PROC_16, TRUE );
308 /***********************************************************************
309 * SetSystemTimer (USER32.@)
311 UINT_PTR WINAPI SetSystemTimer( HWND hwnd, UINT_PTR id, UINT timeout,
312 TIMERPROC proc )
314 TRACE("%p %d %d %p\n", hwnd, id, timeout, proc );
315 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC)proc, WIN_PROC_32A, TRUE );
319 /***********************************************************************
320 * KillTimer (USER32.@)
322 BOOL WINAPI KillTimer( HWND hwnd, UINT_PTR id )
324 TRACE("%p %d\n", hwnd, id );
325 return TIMER_KillTimer( hwnd, id, FALSE );
329 /***********************************************************************
330 * KillSystemTimer (USER32.@)
332 BOOL WINAPI KillSystemTimer( HWND hwnd, UINT_PTR id )
334 TRACE("%p %d\n", hwnd, id );
335 return TIMER_KillTimer( hwnd, id, TRUE );