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

Last change on this file since 1066 was 1066, checked in by dengert, 26 years ago

SetTimer/KillTimer implemented

File size: 5.6 KB
Line 
1/* $Id: timer.cpp,v 1.3 1999-09-26 16:09:04 dengert 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 <os2.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#ifndef OPEN32API
26#define OPEN32API _System
27#endif
28
29#define WM_TIMER_W 0x0113
30typedef VOID (CALLBACK *TIMERPROC)(HWND hwnd, UINT msg, UINT id, DWORD dwTime);
31
32typedef struct tagTIMER
33{
34 enum {free = 0, UserTimer, SystemTimer} inUse;
35 HWND hwnd;
36 UINT id;
37 HWND PMhwnd;
38 ULONG PMid;
39 TIMERPROC proc;
40} TIMER;
41
42#define NB_TIMERS 34
43#define NB_RESERVED_TIMERS 2 /* for SetSystemTimer */
44
45#define SYS_TIMER_RATE 54925
46
47static TIMER TimersArray[NB_TIMERS];
48
49HMTX hSemTimer;
50
51inline void EnterCriticalSection (void)
52{
53 if (hSemTimer == NULLHANDLE)
54 DosCreateMutexSem (NULL, &hSemTimer, 0L, 1);
55 else
56 DosRequestMutexSem (hSemTimer, SEM_INDEFINITE_WAIT);
57}
58
59inline void LeaveCriticalSection (void)
60{
61 DosReleaseMutexSem (hSemTimer);
62}
63
64BOOL TIMER_HandleTimer (PQMSG pMsg)
65{
66 int i;
67 TIMER *pTimer;
68 HWND PMhwnd = pMsg->hwnd;
69 ULONG PMid = (ULONG)(pMsg->mp1);
70
71 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
72 if (pTimer->inUse && (pTimer->PMhwnd == PMhwnd) && (pTimer->PMid == PMid))
73 break;
74
75 if (i == NB_TIMERS) /* no matching timer found */
76 return (TRUE); /* eat message */
77
78 pMsg->mp1 = MPFROMLONG (pTimer->id);
79 if (!pTimer->proc)
80 return (FALSE); /* forward message */
81
82 if (!WinInSendMsg (GetThreadHAB()))
83 pTimer->proc (pTimer->hwnd, WM_TIMER_W, pTimer->id, pMsg->time);
84
85 return (TRUE);
86}
87
88static UINT TIMER_SetTimer (HWND hwnd, UINT id, UINT timeout, TIMERPROC proc, BOOL sys)
89{
90 int i;
91 TIMER *pTimer;
92 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
93
94 if (hwnd && !wnd) return 0;
95
96 EnterCriticalSection ();
97
98 /* Check if there's already a timer with the same hwnd and id */
99
100 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
101 if (pTimer->inUse && (pTimer->hwnd == hwnd) && (pTimer->id == id))
102 break;
103
104 if (i == NB_TIMERS) /* no matching timer found */
105 {
106 /* Find a free timer */
107
108 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
109 if (!pTimer->inUse) break;
110
111 if ((i >= NB_TIMERS) ||
112 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)))
113 {
114 LeaveCriticalSection();
115 return 0;
116 }
117
118 if (!hwnd) id = i + 1;
119
120 /* Add the timer */
121
122 pTimer->inUse = sys ? TIMER::SystemTimer : TIMER::UserTimer;
123 pTimer->hwnd = hwnd;
124 pTimer->id = id;
125 pTimer->proc = proc;
126 pTimer->PMhwnd = hwnd ? wnd->getOS2WindowHandle() : NULLHANDLE;
127 pTimer->PMid = WinStartTimer (GetThreadHAB(), pTimer->PMhwnd,
128 i + 1, timeout);
129
130 if (!pTimer->PMid) id = pTimer->id = 0;
131 } else {
132 WinStartTimer (GetThreadHAB(), pTimer->PMhwnd, pTimer->PMid, timeout);
133 }
134
135 LeaveCriticalSection();
136
137 if (!id) return TRUE;
138 else return id;
139}
140
141static BOOL TIMER_KillTimer (HWND hwnd, UINT id, BOOL sys)
142{
143 int i;
144 TIMER * pTimer;
145
146 EnterCriticalSection();
147
148 /* Find the timer */
149
150 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
151 if (pTimer->inUse &&
152 (pTimer->hwnd == hwnd) && (pTimer->id == id)) break;
153
154 if ((i >= NB_TIMERS) ||
155 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) ||
156 (!sys && (pTimer->inUse != TIMER::UserTimer)) ||
157 (sys && (pTimer->inUse != TIMER::SystemTimer)) )
158 {
159 LeaveCriticalSection();
160 return FALSE;
161 }
162
163 /* Delete the timer */
164
165 WinStopTimer (GetThreadHAB(), pTimer->PMhwnd, pTimer->PMid);
166
167 LeaveCriticalSection();
168
169 return TRUE;
170}
171
172/***********************************************************************
173 * SetTimer32 (USER32.511)
174 */
175UINT WIN32API SetTimer (HWND hwnd, UINT id, UINT timeout, TIMERPROC proc)
176{
177 UINT rc;
178 USHORT sel = RestoreOS2FS();
179
180 dprintf(("USER32: SetTimer %04x %d %d %08lx", hwnd, id, timeout, (LONG)proc));
181
182 rc = TIMER_SetTimer (hwnd, id, timeout, proc, FALSE);
183 SetFS(sel);
184 return (rc);
185}
186
187/***********************************************************************
188 * SetSystemTimer32 (USER32.509)
189 */
190UINT WIN32API SetSystemTimer (HWND hwnd, UINT id, UINT timeout, TIMERPROC proc)
191{
192 UINT rc;
193 USHORT sel = RestoreOS2FS();
194
195 dprintf(("USER32: SetSystemTimer %04x %d %d %08lx", hwnd, id, timeout, (LONG)proc));
196
197 rc = TIMER_SetTimer (hwnd, id, timeout, proc, TRUE);
198 SetFS(sel);
199 return (rc);
200}
201
202/***********************************************************************
203 * KillTimer32 (USER32.354)
204 */
205BOOL WIN32API KillTimer (HWND hwnd, UINT id)
206{
207 BOOL rc;
208 USHORT sel = RestoreOS2FS();
209
210 dprintf(("USER32: KillTimer %04x %d", hwnd, id));
211
212 rc = TIMER_KillTimer (hwnd, id, FALSE);
213 SetFS(sel);
214 return (rc);
215}
216
217/***********************************************************************
218 * KillSystemTimer32 (USER32.353)
219 */
220BOOL WIN32API KillSystemTimer (HWND hwnd, UINT id)
221{
222 BOOL rc;
223 USHORT sel = RestoreOS2FS();
224
225 dprintf(("USER32: KillSystemTimer %04x %d", hwnd, id));
226
227 rc = TIMER_KillTimer (hwnd, id, TRUE);
228 SetFS(sel);
229 return (rc);
230}
231
Note: See TracBrowser for help on using the repository browser.