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

Last change on this file since 1405 was 1405, checked in by sandervl, 26 years ago

Lots of changes/fixes

File size: 5.5 KB
Line 
1/* $Id: timer.cpp,v 1.5 1999-10-22 18:11:47 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 <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 (FALSE); /* forward message */
77
78 pMsg->mp1 = MPFROMLONG (pTimer->id);
79 pMsg->mp2 = MPFROMLONG (TRUE); /* mark for Win32 */
80 if (!pTimer->proc)
81 return (FALSE); /* forward message */
82
83 if (!WinInSendMsg (GetThreadHAB()))
84 pTimer->proc (pTimer->hwnd, WM_TIMER_W, pTimer->id, pMsg->time);
85
86 return (TRUE);
87}
88
89static UINT TIMER_SetTimer (HWND hwnd, UINT id, UINT timeout, TIMERPROC proc, BOOL sys)
90{
91 int i;
92 TIMER *pTimer;
93 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
94
95 if (hwnd && !wnd) return 0;
96
97 EnterCriticalSection ();
98
99 /* Check if there's already a timer with the same hwnd and id */
100
101 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
102 if (pTimer->inUse && (pTimer->hwnd == hwnd) && (pTimer->id == id))
103 break;
104
105 if (i == NB_TIMERS) /* no matching timer found */
106 {
107 /* Find a free timer */
108
109 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
110 if (!pTimer->inUse) break;
111
112 if ((i >= NB_TIMERS) ||
113 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)))
114 {
115 LeaveCriticalSection();
116 return 0;
117 }
118
119 if (!hwnd) id = i + 1;
120
121 /* Add the timer */
122
123 pTimer->inUse = sys ? TIMER::SystemTimer : TIMER::UserTimer;
124 pTimer->hwnd = hwnd;
125 pTimer->id = id;
126 pTimer->proc = proc;
127 pTimer->PMhwnd = hwnd ? wnd->getOS2WindowHandle() : NULLHANDLE;
128 pTimer->PMid = WinStartTimer (GetThreadHAB(), pTimer->PMhwnd,
129 i + 1, timeout);
130
131 if (!pTimer->PMid) id = pTimer->id = 0;
132 } else {
133 WinStartTimer (GetThreadHAB(), pTimer->PMhwnd, pTimer->PMid, timeout);
134 }
135
136 LeaveCriticalSection();
137
138 if (!id) return TRUE;
139 else return id;
140}
141
142static BOOL TIMER_KillTimer (HWND hwnd, UINT id, BOOL sys)
143{
144 int i;
145 TIMER * pTimer;
146
147 EnterCriticalSection();
148
149 /* Find the timer */
150
151 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
152 if (pTimer->inUse &&
153 (pTimer->hwnd == hwnd) && (pTimer->id == id)) break;
154
155 if ((i >= NB_TIMERS) ||
156 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) ||
157 (!sys && (pTimer->inUse != TIMER::UserTimer)) ||
158 (sys && (pTimer->inUse != TIMER::SystemTimer)) )
159 {
160 LeaveCriticalSection();
161 return FALSE;
162 }
163
164 /* Delete the timer */
165
166 WinStopTimer (GetThreadHAB(), pTimer->PMhwnd, pTimer->PMid);
167
168 LeaveCriticalSection();
169
170 return TRUE;
171}
172
173/***********************************************************************
174 * SetTimer32 (USER32.511)
175 */
176UINT WIN32API SetTimer (HWND hwnd, UINT id, UINT timeout, TIMERPROC proc)
177{
178 UINT rc;
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 return (rc);
184}
185
186/***********************************************************************
187 * SetSystemTimer32 (USER32.509)
188 */
189UINT WIN32API SetSystemTimer (HWND hwnd, UINT id, UINT timeout, TIMERPROC proc)
190{
191 UINT rc;
192
193 dprintf(("USER32: SetSystemTimer %04x %d %d %08lx", hwnd, id, timeout, (LONG)proc));
194
195 rc = TIMER_SetTimer (hwnd, id, timeout, proc, TRUE);
196 return (rc);
197}
198
199/***********************************************************************
200 * KillTimer32 (USER32.354)
201 */
202BOOL WIN32API KillTimer (HWND hwnd, UINT id)
203{
204 BOOL rc;
205
206 dprintf(("USER32: KillTimer %04x %d", hwnd, id));
207
208 rc = TIMER_KillTimer (hwnd, id, FALSE);
209 return (rc);
210}
211
212/***********************************************************************
213 * KillSystemTimer32 (USER32.353)
214 */
215BOOL WIN32API KillSystemTimer (HWND hwnd, UINT id)
216{
217 BOOL rc;
218
219 dprintf(("USER32: KillSystemTimer %04x %d", hwnd, id));
220
221 rc = TIMER_KillTimer (hwnd, id, TRUE);
222 return (rc);
223}
224
Note: See TracBrowser for help on using the repository browser.