4 * Copyright 1993 Alexandre Julliard
9 #include "wine/winuser16.h"
16 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(timer
);
21 typedef struct tagTIMER
25 UINT16 msg
; /* WM_TIMER or WM_SYSTIMER */
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 /***********************************************************************
44 * Clear and remove a timer.
46 static void TIMER_ClearTimer( TIMER
* pTimer
)
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
)
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
)
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 /***********************************************************************
99 static UINT
TIMER_SetTimer( HWND hwnd
, UINT id
, UINT timeout
,
100 WNDPROC16 proc
, WINDOWPROCTYPE type
, BOOL sys
)
104 HWINDOWPROC winproc
= 0;
106 if (hwnd
&& GetWindowThreadProcessId( hwnd
, NULL
) != GetCurrentThreadId())
108 SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
113 { /* timeout==0 is a legal argument UB 990821*/
114 WARN("Timeout== 0 not implemented, using timeout=1\n");
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
);
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
);
145 if (!hwnd
) id
= i
+ 1;
147 if (proc
) WINPROC_SetProc( &winproc
, proc
, type
, WIN_PROC_TIMER
);
149 SERVER_START_REQ( set_win_timer
)
152 req
->msg
= sys
? WM_SYSTIMER
: WM_TIMER
;
154 req
->rate
= max( timeout
, SYS_TIMER_RATE
);
155 req
->lparam
= (unsigned int)winproc
;
163 pTimer
->hq
= GetFastQueue16();
164 pTimer
->msg
= sys
? WM_SYSTIMER
: WM_TIMER
;
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
;
180 /***********************************************************************
183 static BOOL
TIMER_KillTimer( HWND hwnd
, UINT id
, BOOL sys
)
188 SERVER_START_REQ( kill_win_timer
)
191 req
->msg
= sys
? WM_SYSTIMER
: WM_TIMER
;
197 EnterCriticalSection( &csTimer
);
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
);
214 /* Delete the timer */
216 TIMER_ClearTimer( pTimer
);
218 LeaveCriticalSection( &csTimer
);
224 /***********************************************************************
227 UINT16 WINAPI
SetTimer16( HWND16 hwnd
, UINT16 id
, UINT16 timeout
,
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
,
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 /***********************************************************************
253 BOOL
TIMER_IsTimerValid( HWND hwnd
, UINT id
, HWINDOWPROC hProc
)
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
))
269 LeaveCriticalSection( &csTimer
);
274 /***********************************************************************
275 * SetSystemTimer (USER.11)
277 UINT16 WINAPI
SetSystemTimer16( HWND16 hwnd
, UINT16 id
, UINT16 timeout
,
280 TRACE("%04x %d %d %08lx\n",
281 hwnd
, id
, timeout
, (LONG
)proc
);
282 return TIMER_SetTimer( hwnd
, id
, timeout
, (WNDPROC16
)proc
,
287 /***********************************************************************
288 * SetSystemTimer (USER32.@)
290 UINT WINAPI
SetSystemTimer( HWND hwnd
, UINT id
, UINT timeout
,
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
);