source: trunk/src/user32/timer.cpp@ 6666

Last change on this file since 6666 was 6269, checked in by sandervl, 24 years ago

* empty log message *

File size: 7.0 KB
Line 
1/* $Id: timer.cpp,v 1.14 2001-07-09 18:09:13 sandervl Exp $ */
2
3/*
4 * timer functions for USER32
5 *
6 * Copyright 1993 Alexandre Julliard
7 * Copyright 1999 Daniela Engert (dani@ngrt.de)
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12
13#define INCL_WIN
14#define INCL_DOSSEMAPHORES
15#define INCL_DOSPROCESS
16#include <os2wrap.h>
17#include <os2sel.h>
18#include <stdlib.h>
19#include "win32type.h"
20#include <winconst.h>
21#include <misc.h>
22#include <win32wbase.h>
23#include "oslibutil.h"
24#include "timer.h"
25
26#define DBG_LOCALLOG DBG_timer
27#include "dbglocal.h"
28
29#ifndef OPEN32API
30#define OPEN32API _System
31#endif
32
33#define WM_TIMER_W 0x0113
34#define WM_SYSTIMER_W 0x0118
35typedef VOID (CALLBACK *TIMERPROC)(HWND hwnd, UINT msg, UINT id, DWORD dwTime);
36
37typedef struct tagTIMER
38{
39 enum {free = 0, UserTimer, SystemTimer} inUse;
40 HWND hwnd;
41 UINT id;
42 HWND PMhwnd;
43 ULONG PMid;
44 TIMERPROC proc;
45} TIMER;
46
47#define NB_TIMERS 34
48#define NB_RESERVED_TIMERS 2 /* for SetSystemTimer */
49
50#define SYS_TIMER_RATE 54925
51
52static TIMER TimersArray[NB_TIMERS];
53
54HMTX hSemTimer;
55
56inline void EnterCriticalSection (void)
57{
58 if (hSemTimer == NULLHANDLE)
59 DosCreateMutexSem (NULL, &hSemTimer, 0L, 1);
60 else
61 DosRequestMutexSem (hSemTimer, SEM_INDEFINITE_WAIT);
62}
63
64inline void LeaveCriticalSection (void)
65{
66 DosReleaseMutexSem (hSemTimer);
67}
68
69BOOL TIMER_GetTimerInfo(HWND PMhwnd,ULONG PMid,PBOOL sys,PULONG id)
70{
71 int i;
72 TIMER *pTimer;
73
74 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
75 if (pTimer->inUse && (pTimer->PMhwnd == PMhwnd) && (pTimer->PMid == PMid))
76 break;
77
78 if (i == NB_TIMERS) /* no matching timer found */
79 return (FALSE); /* forward message */
80
81 *sys = pTimer->inUse == TIMER::SystemTimer;
82 *id = pTimer->id;
83
84 return TRUE;
85}
86
87BOOL TIMER_HandleTimer (PQMSG pMsg)
88{
89 int i;
90 TIMER *pTimer;
91 HWND PMhwnd = pMsg->hwnd;
92 ULONG PMid = (ULONG)(pMsg->mp1);
93
94 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
95 if (pTimer->inUse && (pTimer->PMhwnd == PMhwnd) && (pTimer->PMid == PMid))
96 break;
97
98 if (i == NB_TIMERS) /* no matching timer found */
99 return (FALSE); /* forward message */
100
101 pMsg->mp2 = MPFROMLONG (TRUE); /* mark for Win32 */
102 if (!pTimer->proc)
103 return (FALSE); /* forward message */
104
105 if (!WinInSendMsg (GetThreadHAB())) {
106 dprintf2(("TIMER_HandleTimer %x %x %x", pTimer->hwnd, pTimer->id, pMsg->time));
107 pTimer->proc (pTimer->hwnd, (pTimer->inUse == TIMER::SystemTimer) ? WM_SYSTIMER_W:WM_TIMER_W, pTimer->id, pMsg->time);
108 }
109 return (TRUE);
110}
111
112static UINT TIMER_SetTimer (HWND hwnd, UINT id, UINT timeout, TIMERPROC proc, BOOL sys)
113{
114 int i;
115 TIMER *pTimer;
116 HWND hwndOS2;
117 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
118
119 if (hwnd && !wnd) {
120 dprintf(("TIMER_SetTimer invalid window handle %x", hwnd));
121 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
122 return 0;
123 }
124
125 hwndOS2 = hwnd ? wnd->getOS2WindowHandle() : 0;
126 if(wnd) RELEASE_WNDOBJ(wnd);
127 wnd = NULL;
128
129 EnterCriticalSection ();
130
131 /* Check if there's already a timer with the same hwnd and id */
132
133 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
134 if (pTimer->inUse && (pTimer->hwnd == hwnd) && (pTimer->id == id) && ((sys && pTimer->inUse == TIMER::SystemTimer) || !sys))
135 break;
136
137 if (i == NB_TIMERS) /* no matching timer found */
138 {
139 /* Find a free timer */
140
141 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
142 if (!pTimer->inUse) break;
143
144 if ((i >= NB_TIMERS) ||
145 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)))
146 {
147 LeaveCriticalSection();
148 return 0;
149 }
150
151 if (!hwnd) id = i + 1;
152
153 /* Add the timer */
154
155 pTimer->inUse = sys ? TIMER::SystemTimer : TIMER::UserTimer;
156 pTimer->hwnd = hwnd;
157 pTimer->id = id;
158 pTimer->proc = proc;
159 pTimer->PMhwnd = hwnd ? hwndOS2 : NULLHANDLE;
160 pTimer->PMid = WinStartTimer (GetThreadHAB(), pTimer->PMhwnd,
161 i + 1, timeout);
162
163 if (!pTimer->PMid) id = pTimer->id = 0;
164 } else {
165 WinStartTimer (GetThreadHAB(), pTimer->PMhwnd, pTimer->PMid, timeout);
166 }
167
168 LeaveCriticalSection();
169
170 if (!id) return TRUE;
171 else return id;
172}
173
174static BOOL TIMER_KillTimer (HWND hwnd, UINT id, BOOL sys)
175{
176 int i;
177 TIMER * pTimer;
178
179 EnterCriticalSection();
180
181 /* Find the timer */
182
183 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
184 if (pTimer->inUse &&
185 (pTimer->hwnd == hwnd) && (pTimer->id == id) && ((sys && pTimer->inUse == TIMER::SystemTimer) || !sys)) break;
186
187 if ((i >= NB_TIMERS) ||
188 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) ||
189 (!sys && (pTimer->inUse != TIMER::UserTimer)) ||
190 (sys && (pTimer->inUse != TIMER::SystemTimer)) )
191 {
192 LeaveCriticalSection();
193 return FALSE;
194 }
195
196 /* Delete the timer */
197
198 WinStopTimer (GetThreadHAB(), pTimer->PMhwnd, pTimer->PMid);
199
200 pTimer->inUse = TIMER::free;
201 pTimer->PMhwnd = 0;
202 pTimer->PMid = 0;
203
204 LeaveCriticalSection();
205
206 return TRUE;
207}
208
209VOID TIMER_KillTimerFromWindow(HWND hwnd)
210{
211 int i;
212 TIMER * pTimer;
213
214 if (!IsWindow(hwnd)) return;
215
216 EnterCriticalSection();
217
218 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
219 if (pTimer->inUse && pTimer->hwnd == hwnd)
220 {
221 pTimer->inUse = TIMER::free;
222 pTimer->PMhwnd = 0;
223 pTimer->PMid = 0;
224 }
225
226 LeaveCriticalSection();
227}
228
229/***********************************************************************
230 * SetTimer32 (USER32.511)
231 */
232UINT WIN32API SetTimer (HWND hwnd, UINT id, UINT timeout, TIMERPROC proc)
233{
234 UINT rc;
235
236 dprintf(("USER32: SetTimer %x %d %d %08lx", hwnd, id, timeout, (LONG)proc));
237
238 rc = TIMER_SetTimer (hwnd, id, timeout, proc, FALSE);
239 return (rc);
240}
241
242/***********************************************************************
243 * SetSystemTimer32 (USER32.509)
244 */
245UINT WIN32API SetSystemTimer (HWND hwnd, UINT id, UINT timeout, TIMERPROC proc)
246{
247 UINT rc;
248
249 dprintf(("USER32: SetSystemTimer %04x %d %d %08lx", hwnd, id, timeout, (LONG)proc));
250
251 rc = TIMER_SetTimer (hwnd, id, timeout, proc, TRUE);
252 return (rc);
253}
254
255/***********************************************************************
256 * KillTimer32 (USER32.354)
257 */
258BOOL WIN32API KillTimer (HWND hwnd, UINT id)
259{
260 BOOL rc;
261
262 dprintf(("USER32: KillTimer %x %d", hwnd, id));
263
264 rc = TIMER_KillTimer (hwnd, id, FALSE);
265 return (rc);
266}
267
268/***********************************************************************
269 * KillSystemTimer32 (USER32.353)
270 */
271BOOL WIN32API KillSystemTimer (HWND hwnd, UINT id)
272{
273 BOOL rc;
274
275 dprintf(("USER32: KillSystemTimer %x %d", hwnd, id));
276
277 rc = TIMER_KillTimer (hwnd, id, TRUE);
278 return (rc);
279}
280
Note: See TracBrowser for help on using the repository browser.