Fix PathCreateFromUrl{A|W} to return the corrrect error code in all
[wine.git] / windows / timer.c
blob2dc61fd7d7723a557a6a17003bac0ab621e0faa2
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 "win.h"
16 #include "wine/server.h"
17 #include "debugtools.h"
19 DEFAULT_DEBUG_CHANNEL(timer);
22 typedef struct tagTIMER
24 HWND hwnd;
25 HQUEUE16 hq;
26 UINT16 msg; /* WM_TIMER or WM_SYSTIMER */
27 UINT id;
28 UINT timeout;
29 HWINDOWPROC proc;
30 } TIMER;
32 #define NB_TIMERS 34
33 #define NB_RESERVED_TIMERS 2 /* for SetSystemTimer */
35 #define SYS_TIMER_RATE 55 /* min. timer rate in ms (actually 54.925)*/
37 static TIMER TimersArray[NB_TIMERS];
39 static CRITICAL_SECTION csTimer = CRITICAL_SECTION_INIT("csTimer");
42 /***********************************************************************
43 * TIMER_ClearTimer
45 * Clear and remove a timer.
47 static void TIMER_ClearTimer( TIMER * pTimer )
49 pTimer->hwnd = 0;
50 pTimer->msg = 0;
51 pTimer->id = 0;
52 pTimer->timeout = 0;
53 WINPROC_FreeProc( pTimer->proc, WIN_PROC_TIMER );
57 /***********************************************************************
58 * TIMER_RemoveWindowTimers
60 * Remove all timers for a given window.
62 void TIMER_RemoveWindowTimers( HWND hwnd )
64 int i;
65 TIMER *pTimer;
67 EnterCriticalSection( &csTimer );
69 for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
70 if ((pTimer->hwnd == hwnd) && pTimer->timeout)
71 TIMER_ClearTimer( pTimer );
73 LeaveCriticalSection( &csTimer );
77 /***********************************************************************
78 * TIMER_RemoveQueueTimers
80 * Remove all timers for a given queue.
82 void TIMER_RemoveQueueTimers( HQUEUE16 hqueue )
84 int i;
85 TIMER *pTimer;
87 EnterCriticalSection( &csTimer );
89 for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
90 if ((pTimer->hq == hqueue) && pTimer->timeout)
91 TIMER_ClearTimer( pTimer );
93 LeaveCriticalSection( &csTimer );
97 /***********************************************************************
98 * TIMER_SetTimer
100 static UINT TIMER_SetTimer( HWND hwnd, UINT id, UINT timeout,
101 WNDPROC16 proc, WINDOWPROCTYPE type, BOOL sys )
103 int i;
104 TIMER * pTimer;
105 HWINDOWPROC winproc = 0;
107 if (hwnd && !(hwnd = WIN_IsCurrentThread( hwnd )))
109 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
110 return 0;
113 if (!timeout)
114 { /* timeout==0 is a legal argument UB 990821*/
115 WARN("Timeout== 0 not implemented, using timeout=1\n");
116 timeout=1;
119 EnterCriticalSection( &csTimer );
121 /* Check if there's already a timer with the same hwnd and id */
123 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
124 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
125 (pTimer->timeout != 0))
127 TIMER_ClearTimer( pTimer );
128 break;
131 if ( i == NB_TIMERS )
133 /* Find a free timer */
135 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
136 if (!pTimer->timeout) break;
138 if ( (i >= NB_TIMERS) ||
139 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) )
141 LeaveCriticalSection( &csTimer );
142 return 0;
146 if (!hwnd) id = i + 1;
148 if (proc) WINPROC_SetProc( &winproc, proc, type, WIN_PROC_TIMER );
150 SERVER_START_REQ( set_win_timer )
152 req->win = hwnd;
153 req->msg = sys ? WM_SYSTIMER : WM_TIMER;
154 req->id = id;
155 req->rate = max( timeout, SYS_TIMER_RATE );
156 req->lparam = (unsigned int)winproc;
157 wine_server_call( req );
159 SERVER_END_REQ;
161 /* Add the timer */
163 pTimer->hwnd = hwnd;
164 pTimer->hq = InitThreadInput16( 0, 0 );
165 pTimer->msg = sys ? WM_SYSTIMER : WM_TIMER;
166 pTimer->id = id;
167 pTimer->timeout = timeout;
168 pTimer->proc = winproc;
170 TRACE("Timer added: %p, %04x, %04x, %04x, %08lx\n",
171 pTimer, pTimer->hwnd, pTimer->msg, pTimer->id,
172 (DWORD)pTimer->proc );
174 LeaveCriticalSection( &csTimer );
176 if (!id) return TRUE;
177 else return id;
181 /***********************************************************************
182 * TIMER_KillTimer
184 static BOOL TIMER_KillTimer( HWND hwnd, UINT id, BOOL sys )
186 int i;
187 TIMER * pTimer;
189 SERVER_START_REQ( kill_win_timer )
191 req->win = hwnd;
192 req->msg = sys ? WM_SYSTIMER : WM_TIMER;
193 req->id = id;
194 wine_server_call( req );
196 SERVER_END_REQ;
198 EnterCriticalSection( &csTimer );
200 /* Find the timer */
202 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
203 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
204 (pTimer->timeout != 0)) break;
206 if ( (i >= NB_TIMERS) ||
207 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) ||
208 (!sys && (pTimer->msg != WM_TIMER)) ||
209 (sys && (pTimer->msg != WM_SYSTIMER)) )
211 LeaveCriticalSection( &csTimer );
212 return FALSE;
215 /* Delete the timer */
217 TIMER_ClearTimer( pTimer );
219 LeaveCriticalSection( &csTimer );
221 return TRUE;
225 /***********************************************************************
226 * SetTimer (USER.10)
228 UINT16 WINAPI SetTimer16( HWND16 hwnd, UINT16 id, UINT16 timeout,
229 TIMERPROC16 proc )
231 TRACE("%04x %d %d %08lx\n",
232 hwnd, id, timeout, (LONG)proc );
233 return TIMER_SetTimer( WIN_Handle32(hwnd), id, timeout, (WNDPROC16)proc,
234 WIN_PROC_16, FALSE );
238 /***********************************************************************
239 * SetTimer (USER32.@)
241 UINT WINAPI SetTimer( HWND hwnd, UINT id, UINT timeout,
242 TIMERPROC proc )
244 TRACE("%04x %d %d %08lx\n",
245 hwnd, id, timeout, (LONG)proc );
246 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc, 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 hwnd = WIN_GetFullHandle( hwnd );
260 EnterCriticalSection( &csTimer );
262 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
263 if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
264 (pTimer->proc == hProc))
266 ret = TRUE;
267 break;
270 LeaveCriticalSection( &csTimer );
271 return ret;
275 /***********************************************************************
276 * SetSystemTimer (USER.11)
278 UINT16 WINAPI SetSystemTimer16( HWND16 hwnd, UINT16 id, UINT16 timeout,
279 TIMERPROC16 proc )
281 TRACE("%04x %d %d %08lx\n",
282 hwnd, id, timeout, (LONG)proc );
283 return TIMER_SetTimer( WIN_Handle32(hwnd), id, timeout, (WNDPROC16)proc,
284 WIN_PROC_16, TRUE );
288 /***********************************************************************
289 * SetSystemTimer (USER32.@)
291 UINT WINAPI SetSystemTimer( HWND hwnd, UINT id, UINT timeout,
292 TIMERPROC proc )
294 TRACE("%04x %d %d %08lx\n",
295 hwnd, id, timeout, (LONG)proc );
296 return TIMER_SetTimer( hwnd, id, timeout, (WNDPROC16)proc, WIN_PROC_32A, TRUE );
300 /***********************************************************************
301 * KillTimer (USER32.@)
303 BOOL WINAPI KillTimer( HWND hwnd, UINT id )
305 TRACE("%04x %d\n", hwnd, id );
306 return TIMER_KillTimer( hwnd, id, FALSE );
310 /***********************************************************************
311 * KillSystemTimer (USER32.@)
313 BOOL WINAPI KillSystemTimer( HWND hwnd, UINT id )
315 TRACE("%04x %d\n", hwnd, id );
316 return TIMER_KillTimer( hwnd, id, TRUE );