Avoid including wine/obj_*.h files directly from C files.
[wine/multimedia.git] / windows / timer.c
blobede31342bcac63607f53624b182973a43aad7b94
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 "windef.h"
22 #include "wingdi.h"
23 #include "wine/winuser16.h"
24 #include "winuser.h"
25 #include "winerror.h"
27 #include "winproc.h"
28 #include "message.h"
29 #include "win.h"
30 #include "wine/server.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(timer);
36 typedef struct tagTIMER
38 HWND hwnd;
39 DWORD thread;
40 UINT msg; /* WM_TIMER or WM_SYSTIMER */
41 UINT id;
42 UINT timeout;
43 WNDPROC proc;
44 } TIMER;
46 #define NB_TIMERS 34
47 #define NB_RESERVED_TIMERS 2 /* for SetSystemTimer */
49 #define SYS_TIMER_RATE 55 /* min. timer rate in ms (actually 54.925)*/
51 static TIMER TimersArray[NB_TIMERS];
53 static CRITICAL_SECTION csTimer;
54 static CRITICAL_SECTION_DEBUG critsect_debug =
56 0, 0, &csTimer,
57 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
58 0, 0, { 0, (DWORD)(__FILE__ ": csTimer") }
60 static CRITICAL_SECTION csTimer = { &critsect_debug, -1, 0, 0, 0, 0 };
63 /***********************************************************************
64 * TIMER_ClearTimer
66 * Clear and remove a timer.
68 static void TIMER_ClearTimer( TIMER * pTimer )
70 pTimer->hwnd = 0;
71 pTimer->msg = 0;
72 pTimer->id = 0;
73 pTimer->timeout = 0;
74 WINPROC_FreeProc( pTimer->proc, WIN_PROC_TIMER );
78 /***********************************************************************
79 * TIMER_RemoveWindowTimers
81 * Remove all timers for a given window.
83 void TIMER_RemoveWindowTimers( HWND hwnd )
85 int i;
86 TIMER *pTimer;
88 EnterCriticalSection( &csTimer );
90 for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
91 if ((pTimer->hwnd == hwnd) && pTimer->timeout)
92 TIMER_ClearTimer( pTimer );
94 LeaveCriticalSection( &csTimer );
98 /***********************************************************************
99 * TIMER_RemoveThreadTimers
101 * Remove all timers for the current thread.
103 void TIMER_RemoveThreadTimers(void)
105 int i;
106 TIMER *pTimer;
108 EnterCriticalSection( &csTimer );
110 for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
111 if ((pTimer->thread == GetCurrentThreadId()) && pTimer->timeout)
112 TIMER_ClearTimer( pTimer );
114 LeaveCriticalSection( &csTimer );
118 /***********************************************************************
119 * TIMER_SetTimer
121 static UINT_PTR TIMER_SetTimer( HWND hwnd, UINT_PTR id, UINT timeout,
122 WNDPROC proc, WINDOWPROCTYPE type, BOOL sys )
124 int i;
125 TIMER * pTimer;
126 WNDPROC winproc = 0;
128 if (hwnd && !(hwnd = WIN_IsCurrentThread( hwnd )))
130 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
131 return 0;
134 if (!timeout)
135 { /* timeout==0 is a legal argument UB 990821*/
136 WARN("Timeout== 0 not implemented, using timeout=1\n");
137 timeout=1;
140 EnterCriticalSection( &csTimer );
142 /* Check if there's already a timer with the same hwnd and id */
144 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
145 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
146 (pTimer->timeout != 0))
148 TIMER_ClearTimer( pTimer );
149 break;
152 if ( i == NB_TIMERS )
154 /* Find a free timer */
156 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
157 if (!pTimer->timeout) break;
159 if ( (i >= NB_TIMERS) ||
160 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) )
162 LeaveCriticalSection( &csTimer );
163 return 0;
167 if (!hwnd) id = i + 1;
169 if (proc) WINPROC_SetProc( &winproc, proc, type, WIN_PROC_TIMER );
171 SERVER_START_REQ( set_win_timer )
173 req->win = hwnd;
174 req->msg = sys ? WM_SYSTIMER : WM_TIMER;
175 req->id = id;
176 req->rate = max( timeout, SYS_TIMER_RATE );
177 req->lparam = (unsigned int)winproc;
178 wine_server_call( req );
180 SERVER_END_REQ;
182 /* Add the timer */
184 pTimer->hwnd = hwnd;
185 pTimer->thread = GetCurrentThreadId();
186 pTimer->msg = sys ? WM_SYSTIMER : WM_TIMER;
187 pTimer->id = id;
188 pTimer->timeout = timeout;
189 pTimer->proc = winproc;
191 TRACE("Timer added: %p, %p, %04x, %04x, %p\n",
192 pTimer, pTimer->hwnd, pTimer->msg, pTimer->id, pTimer->proc );
194 LeaveCriticalSection( &csTimer );
196 if (!id) return TRUE;
197 else return id;
201 /***********************************************************************
202 * TIMER_KillTimer
204 static BOOL TIMER_KillTimer( HWND hwnd, UINT_PTR id, BOOL sys )
206 int i;
207 TIMER * pTimer;
209 SERVER_START_REQ( kill_win_timer )
211 req->win = hwnd;
212 req->msg = sys ? WM_SYSTIMER : WM_TIMER;
213 req->id = id;
214 wine_server_call( req );
216 SERVER_END_REQ;
218 EnterCriticalSection( &csTimer );
220 /* Find the timer */
222 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
223 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
224 (pTimer->timeout != 0)) break;
226 if ( (i >= NB_TIMERS) ||
227 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) ||
228 (!sys && (pTimer->msg != WM_TIMER)) ||
229 (sys && (pTimer->msg != WM_SYSTIMER)) )
231 LeaveCriticalSection( &csTimer );
232 return FALSE;
235 /* Delete the timer */
237 TIMER_ClearTimer( pTimer );
239 LeaveCriticalSection( &csTimer );
241 return TRUE;
245 /***********************************************************************
246 * SetTimer (USER.10)
248 UINT16 WINAPI SetTimer16( HWND16 hwnd, UINT16 id, UINT16 timeout,
249 TIMERPROC16 proc )
251 TRACE("%04x %d %d %08lx\n",
252 hwnd, id, timeout, (LONG)proc );
253 return TIMER_SetTimer( WIN_Handle32(hwnd), id, timeout, (WNDPROC)proc,
254 WIN_PROC_16, FALSE );
258 /***********************************************************************
259 * SetTimer (USER32.@)
261 UINT_PTR WINAPI SetTimer( HWND hwnd, UINT_PTR id, UINT timeout,
262 TIMERPROC proc )
264 TRACE("%p %d %d %p\n", hwnd, id, timeout, proc );
265 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC)proc, WIN_PROC_32A, FALSE );
269 /***********************************************************************
270 * TIMER_IsTimerValid
272 BOOL TIMER_IsTimerValid( HWND hwnd, UINT_PTR id, WNDPROC proc )
274 int i;
275 TIMER *pTimer;
276 BOOL ret = FALSE;
278 hwnd = WIN_GetFullHandle( hwnd );
279 EnterCriticalSection( &csTimer );
281 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
282 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) && (pTimer->proc == proc))
284 ret = TRUE;
285 break;
288 LeaveCriticalSection( &csTimer );
289 return ret;
293 /***********************************************************************
294 * SetSystemTimer (USER.11)
296 UINT16 WINAPI SetSystemTimer16( HWND16 hwnd, UINT16 id, UINT16 timeout,
297 TIMERPROC16 proc )
299 TRACE("%04x %d %d %08lx\n",
300 hwnd, id, timeout, (LONG)proc );
301 return TIMER_SetTimer( WIN_Handle32(hwnd), id, timeout, (WNDPROC)proc, WIN_PROC_16, TRUE );
305 /***********************************************************************
306 * SetSystemTimer (USER32.@)
308 UINT_PTR WINAPI SetSystemTimer( HWND hwnd, UINT_PTR id, UINT timeout,
309 TIMERPROC proc )
311 TRACE("%p %d %d %p\n", hwnd, id, timeout, proc );
312 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC)proc, WIN_PROC_32A, TRUE );
316 /***********************************************************************
317 * KillTimer (USER32.@)
319 BOOL WINAPI KillTimer( HWND hwnd, UINT_PTR id )
321 TRACE("%p %d\n", hwnd, id );
322 return TIMER_KillTimer( hwnd, id, FALSE );
326 /***********************************************************************
327 * KillSystemTimer (USER32.@)
329 BOOL WINAPI KillSystemTimer( HWND hwnd, UINT_PTR id )
331 TRACE("%p %d\n", hwnd, id );
332 return TIMER_KillTimer( hwnd, id, TRUE );