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

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

caret blinking and recreation

File size: 5.7 KB
Line 
1/* $Id: timer.cpp,v 1.4 1999-09-29 09:31:18 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 (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 USHORT sel = RestoreOS2FS();
180
181 dprintf(("USER32: SetTimer %04x %d %d %08lx", hwnd, id, timeout, (LONG)proc));
182
183 rc = TIMER_SetTimer (hwnd, id, timeout, proc, FALSE);
184 SetFS(sel);
185 return (rc);
186}
187
188/***********************************************************************
189 * SetSystemTimer32 (USER32.509)
190 */
191UINT WIN32API SetSystemTimer (HWND hwnd, UINT id, UINT timeout, TIMERPROC proc)
192{
193 UINT rc;
194 USHORT sel = RestoreOS2FS();
195
196 dprintf(("USER32: SetSystemTimer %04x %d %d %08lx", hwnd, id, timeout, (LONG)proc));
197
198 rc = TIMER_SetTimer (hwnd, id, timeout, proc, TRUE);
199 SetFS(sel);
200 return (rc);
201}
202
203/***********************************************************************
204 * KillTimer32 (USER32.354)
205 */
206BOOL WIN32API KillTimer (HWND hwnd, UINT id)
207{
208 BOOL rc;
209 USHORT sel = RestoreOS2FS();
210
211 dprintf(("USER32: KillTimer %04x %d", hwnd, id));
212
213 rc = TIMER_KillTimer (hwnd, id, FALSE);
214 SetFS(sel);
215 return (rc);
216}
217
218/***********************************************************************
219 * KillSystemTimer32 (USER32.353)
220 */
221BOOL WIN32API KillSystemTimer (HWND hwnd, UINT id)
222{
223 BOOL rc;
224 USHORT sel = RestoreOS2FS();
225
226 dprintf(("USER32: KillSystemTimer %04x %d", hwnd, id));
227
228 rc = TIMER_KillTimer (hwnd, id, TRUE);
229 SetFS(sel);
230 return (rc);
231}
232
Note: See TracBrowser for help on using the repository browser.