Release 20040914.
[wine/gsoc-2012-control.git] / windows / timer.c
blob30d4677a8bac38da96c79775ab8e7fd2a6939090
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 "config.h"
22 #include "wine/port.h"
24 #include <stdarg.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "wine/winuser16.h"
30 #include "winuser.h"
31 #include "winerror.h"
33 #include "winproc.h"
34 #include "message.h"
35 #include "win.h"
36 #include "wine/server.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(timer);
42 typedef struct tagTIMER
44 HWND hwnd;
45 DWORD thread;
46 UINT msg; /* WM_TIMER or WM_SYSTIMER */
47 UINT id;
48 UINT timeout;
49 WNDPROC proc;
50 } TIMER;
52 #define NB_TIMERS 34
53 #define NB_RESERVED_TIMERS 2 /* for SetSystemTimer */
55 #define SYS_TIMER_RATE 55 /* min. timer rate in ms (actually 54.925)*/
57 static TIMER TimersArray[NB_TIMERS];
59 static CRITICAL_SECTION csTimer;
60 static CRITICAL_SECTION_DEBUG critsect_debug =
62 0, 0, &csTimer,
63 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
64 0, 0, { 0, (DWORD)(__FILE__ ": csTimer") }
66 static CRITICAL_SECTION csTimer = { &critsect_debug, -1, 0, 0, 0, 0 };
69 /***********************************************************************
70 * TIMER_ClearTimer
72 * Clear and remove a timer.
74 static void TIMER_ClearTimer( TIMER * pTimer )
76 pTimer->hwnd = 0;
77 pTimer->msg = 0;
78 pTimer->id = 0;
79 pTimer->timeout = 0;
80 WINPROC_FreeProc( pTimer->proc, WIN_PROC_TIMER );
84 /***********************************************************************
85 * TIMER_RemoveWindowTimers
87 * Remove all timers for a given window.
89 void TIMER_RemoveWindowTimers( HWND hwnd )
91 int i;
92 TIMER *pTimer;
94 EnterCriticalSection( &csTimer );
96 for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
97 if ((pTimer->hwnd == hwnd) && pTimer->timeout)
98 TIMER_ClearTimer( pTimer );
100 LeaveCriticalSection( &csTimer );
104 /***********************************************************************
105 * TIMER_RemoveThreadTimers
107 * Remove all timers for the current thread.
109 void TIMER_RemoveThreadTimers(void)
111 int i;
112 TIMER *pTimer;
114 EnterCriticalSection( &csTimer );
116 for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
117 if ((pTimer->thread == GetCurrentThreadId()) && pTimer->timeout)
118 TIMER_ClearTimer( pTimer );
120 LeaveCriticalSection( &csTimer );
124 /***********************************************************************
125 * TIMER_SetTimer
127 static UINT_PTR TIMER_SetTimer( HWND hwnd, UINT_PTR id, UINT timeout,
128 WNDPROC proc, WINDOWPROCTYPE type, BOOL sys )
130 int i;
131 TIMER * pTimer;
132 WNDPROC winproc = 0;
134 if (hwnd && !(hwnd = WIN_IsCurrentThread( hwnd )))
136 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
137 return 0;
140 if (!timeout)
141 { /* timeout==0 is a legal argument UB 990821*/
142 WARN("Timeout== 0 not implemented, using timeout=1\n");
143 timeout=1;
146 EnterCriticalSection( &csTimer );
148 /* Check if there's already a timer with the same hwnd and id */
150 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
151 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
152 (pTimer->timeout != 0))
154 TIMER_ClearTimer( pTimer );
155 break;
158 if ( i == NB_TIMERS )
160 /* Find a free timer */
162 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
163 if (!pTimer->timeout) break;
165 if ( (i >= NB_TIMERS) ||
166 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) )
168 LeaveCriticalSection( &csTimer );
169 return 0;
173 if (!hwnd) id = i + 1;
175 if (proc) WINPROC_SetProc( &winproc, proc, type, WIN_PROC_TIMER );
177 SERVER_START_REQ( set_win_timer )
179 req->win = hwnd;
180 req->msg = sys ? WM_SYSTIMER : WM_TIMER;
181 req->id = id;
182 req->rate = max( timeout, SYS_TIMER_RATE );
183 req->lparam = (unsigned int)winproc;
184 wine_server_call( req );
186 SERVER_END_REQ;
188 /* Add the timer */
190 pTimer->hwnd = hwnd;
191 pTimer->thread = GetCurrentThreadId();
192 pTimer->msg = sys ? WM_SYSTIMER : WM_TIMER;
193 pTimer->id = id;
194 pTimer->timeout = timeout;
195 pTimer->proc = winproc;
197 TRACE("Timer added: %p, %p, %04x, %04x, %p\n",
198 pTimer, pTimer->hwnd, pTimer->msg, pTimer->id, pTimer->proc );
200 LeaveCriticalSection( &csTimer );
202 if (!id) return TRUE;
203 else return id;
207 /***********************************************************************
208 * TIMER_KillTimer
210 static BOOL TIMER_KillTimer( HWND hwnd, UINT_PTR id, BOOL sys )
212 int i;
213 TIMER * pTimer;
215 SERVER_START_REQ( kill_win_timer )
217 req->win = hwnd;
218 req->msg = sys ? WM_SYSTIMER : WM_TIMER;
219 req->id = id;
220 wine_server_call( req );
222 SERVER_END_REQ;
224 EnterCriticalSection( &csTimer );
226 /* Find the timer */
228 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
229 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
230 (pTimer->timeout != 0)) break;
232 if ( (i >= NB_TIMERS) ||
233 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) ||
234 (!sys && (pTimer->msg != WM_TIMER)) ||
235 (sys && (pTimer->msg != WM_SYSTIMER)) )
237 LeaveCriticalSection( &csTimer );
238 return FALSE;
241 /* Delete the timer */
243 TIMER_ClearTimer( pTimer );
245 LeaveCriticalSection( &csTimer );
247 return TRUE;
251 /***********************************************************************
252 * SetTimer (USER.10)
254 UINT16 WINAPI SetTimer16( HWND16 hwnd, UINT16 id, UINT16 timeout,
255 TIMERPROC16 proc )
257 TRACE("%04x %d %d %08lx\n",
258 hwnd, id, timeout, (LONG)proc );
259 return TIMER_SetTimer( WIN_Handle32(hwnd), id, timeout, (WNDPROC)proc,
260 WIN_PROC_16, FALSE );
264 /***********************************************************************
265 * SetTimer (USER32.@)
267 UINT_PTR WINAPI SetTimer( HWND hwnd, UINT_PTR id, UINT timeout,
268 TIMERPROC proc )
270 TRACE("%p %d %d %p\n", hwnd, id, timeout, proc );
271 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC)proc, WIN_PROC_32A, FALSE );
275 /***********************************************************************
276 * TIMER_IsTimerValid
278 BOOL TIMER_IsTimerValid( HWND hwnd, UINT_PTR id, WNDPROC proc )
280 int i;
281 TIMER *pTimer;
282 BOOL ret = FALSE;
284 hwnd = WIN_GetFullHandle( hwnd );
285 EnterCriticalSection( &csTimer );
287 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
288 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) && (pTimer->proc == proc))
290 ret = TRUE;
291 break;
294 LeaveCriticalSection( &csTimer );
295 return ret;
299 /***********************************************************************
300 * SetSystemTimer (USER.11)
302 UINT16 WINAPI SetSystemTimer16( HWND16 hwnd, UINT16 id, UINT16 timeout,
303 TIMERPROC16 proc )
305 TRACE("%04x %d %d %08lx\n",
306 hwnd, id, timeout, (LONG)proc );
307 return TIMER_SetTimer( WIN_Handle32(hwnd), id, timeout, (WNDPROC)proc, WIN_PROC_16, TRUE );
311 /***********************************************************************
312 * SetSystemTimer (USER32.@)
314 UINT_PTR WINAPI SetSystemTimer( HWND hwnd, UINT_PTR id, UINT timeout,
315 TIMERPROC proc )
317 TRACE("%p %d %d %p\n", hwnd, id, timeout, proc );
318 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC)proc, WIN_PROC_32A, TRUE );
322 /***********************************************************************
323 * KillTimer (USER32.@)
325 BOOL WINAPI KillTimer( HWND hwnd, UINT_PTR id )
327 TRACE("%p %d\n", hwnd, id );
328 return TIMER_KillTimer( hwnd, id, FALSE );
332 /***********************************************************************
333 * KillSystemTimer (USER32.@)
335 BOOL WINAPI KillSystemTimer( HWND hwnd, UINT_PTR id )
337 TRACE("%p %d\n", hwnd, id );
338 return TIMER_KillTimer( hwnd, id, TRUE );