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

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

reference count (window + class objects) rewrite

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