00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #define INCL_WIN
00014 #define INCL_DOSSEMAPHORES
00015 #define INCL_DOSPROCESS
00016 #include <os2wrap.h>
00017 #include <os2sel.h>
00018 #include <stdlib.h>
00019 #include "win32type.h"
00020 #include <winconst.h>
00021 #include <misc.h>
00022 #include <win32wbase.h>
00023 #include "oslibutil.h"
00024 #include "timer.h"
00025
00026 #define DBG_LOCALLOG DBG_timer
00027 #include "dbglocal.h"
00028
00029 #ifndef OPEN32API
00030 #define OPEN32API _System
00031 #endif
00032
00033 #define WM_TIMER_W 0x0113
00034 #define WM_SYSTIMER_W 0x0118
00035 typedef VOID (CALLBACK *TIMERPROC)(HWND hwnd, UINT msg, UINT id, DWORD dwTime);
00036
00037 typedef struct tagTIMER
00038 {
00039 enum {free = 0, UserTimer, SystemTimer} inUse;
00040 HWND hwnd;
00041 UINT id;
00042 HWND PMhwnd;
00043 ULONG PMid;
00044 TIMERPROC proc;
00045 } TIMER;
00046
00047 #define NB_TIMERS 34
00048 #define NB_RESERVED_TIMERS 2
00049
00050 #define SYS_TIMER_RATE 54925
00051
00052 static TIMER TimersArray[NB_TIMERS];
00053
00054 HMTX hSemTimer;
00055
00056 inline void EnterCriticalSection (void)
00057 {
00058 if (hSemTimer == NULLHANDLE)
00059 DosCreateMutexSem (NULL, &hSemTimer, 0L, 1);
00060 else
00061 DosRequestMutexSem (hSemTimer, SEM_INDEFINITE_WAIT);
00062 }
00063
00064 inline void LeaveCriticalSection (void)
00065 {
00066 DosReleaseMutexSem (hSemTimer);
00067 }
00068
00069 BOOL TIMER_GetTimerInfo(HWND PMhwnd,ULONG PMid,PBOOL sys,PULONG id)
00070 {
00071 int i;
00072 TIMER *pTimer;
00073
00074 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
00075 if (pTimer->inUse && (pTimer->PMhwnd == PMhwnd) && (pTimer->PMid == PMid))
00076 break;
00077
00078 if (i == NB_TIMERS)
00079 return (FALSE);
00080
00081 *sys = pTimer->inUse == TIMER::SystemTimer;
00082 *id = pTimer->id;
00083
00084 return TRUE;
00085 }
00086
00087 BOOL TIMER_HandleTimer (PQMSG pMsg)
00088 {
00089 int i;
00090 TIMER *pTimer;
00091 HWND PMhwnd = pMsg->hwnd;
00092 ULONG PMid = (ULONG)(pMsg->mp1);
00093
00094 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
00095 if (pTimer->inUse && (pTimer->PMhwnd == PMhwnd) && (pTimer->PMid == PMid))
00096 break;
00097
00098 if (i == NB_TIMERS)
00099 return (FALSE);
00100
00101 pMsg->mp2 = MPFROMLONG (TRUE);
00102 if (!pTimer->proc)
00103 return (FALSE);
00104
00105 if (!WinInSendMsg (GetThreadHAB())) {
00106 dprintf2(("TIMER_HandleTimer %x %x %x", pTimer->hwnd, pTimer->id, pMsg->time));
00107 pTimer->proc (pTimer->hwnd, (pTimer->inUse == TIMER::SystemTimer) ? WM_SYSTIMER_W:WM_TIMER_W, pTimer->id, pMsg->time);
00108 }
00109 return (TRUE);
00110 }
00111
00112 static UINT TIMER_SetTimer (HWND hwnd, UINT id, UINT timeout, TIMERPROC proc, BOOL sys)
00113 {
00114 int i;
00115 TIMER *pTimer;
00116 HWND hwndOS2;
00117 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
00118
00119 if (hwnd && !wnd) {
00120 dprintf(("TIMER_SetTimer invalid window handle %x", hwnd));
00121 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
00122 return 0;
00123 }
00124
00125 hwndOS2 = hwnd ? wnd->getOS2WindowHandle() : 0;
00126 if(wnd) RELEASE_WNDOBJ(wnd);
00127 wnd = NULL;
00128
00129 EnterCriticalSection ();
00130
00131
00132
00133 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
00134 if (pTimer->inUse && (pTimer->hwnd == hwnd) && (pTimer->id == id) && ((sys && pTimer->inUse == TIMER::SystemTimer) || !sys))
00135 break;
00136
00137 if (i == NB_TIMERS)
00138 {
00139
00140
00141 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
00142 if (!pTimer->inUse) break;
00143
00144 if ((i >= NB_TIMERS) ||
00145 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)))
00146 {
00147 LeaveCriticalSection();
00148 return 0;
00149 }
00150
00151 if (!hwnd) id = i + 1;
00152
00153
00154
00155 pTimer->inUse = sys ? TIMER::SystemTimer : TIMER::UserTimer;
00156 pTimer->hwnd = hwnd;
00157 pTimer->id = id;
00158 pTimer->proc = proc;
00159 pTimer->PMhwnd = hwnd ? hwndOS2 : NULLHANDLE;
00160 pTimer->PMid = WinStartTimer (GetThreadHAB(), pTimer->PMhwnd,
00161 i + 1, timeout);
00162
00163 if (!pTimer->PMid) id = pTimer->id = 0;
00164 } else {
00165 WinStartTimer (GetThreadHAB(), pTimer->PMhwnd, pTimer->PMid, timeout);
00166 }
00167
00168 LeaveCriticalSection();
00169
00170 if (!id) return TRUE;
00171 else return id;
00172 }
00173
00174 static BOOL TIMER_KillTimer (HWND hwnd, UINT id, BOOL sys)
00175 {
00176 int i;
00177 TIMER * pTimer;
00178
00179 EnterCriticalSection();
00180
00181
00182
00183 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
00184 if (pTimer->inUse &&
00185 (pTimer->hwnd == hwnd) && (pTimer->id == id) && ((sys && pTimer->inUse == TIMER::SystemTimer) || !sys)) break;
00186
00187 if ((i >= NB_TIMERS) ||
00188 (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) ||
00189 (!sys && (pTimer->inUse != TIMER::UserTimer)) ||
00190 (sys && (pTimer->inUse != TIMER::SystemTimer)) )
00191 {
00192 LeaveCriticalSection();
00193 return FALSE;
00194 }
00195
00196
00197
00198 WinStopTimer (GetThreadHAB(), pTimer->PMhwnd, pTimer->PMid);
00199
00200 pTimer->inUse = TIMER::free;
00201 pTimer->PMhwnd = 0;
00202 pTimer->PMid = 0;
00203
00204 LeaveCriticalSection();
00205
00206 return TRUE;
00207 }
00208
00209 VOID TIMER_KillTimerFromWindow(HWND hwnd)
00210 {
00211 int i;
00212 TIMER * pTimer;
00213
00214 if (!IsWindow(hwnd)) return;
00215
00216 EnterCriticalSection();
00217
00218 for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
00219 if (pTimer->inUse && pTimer->hwnd == hwnd)
00220 {
00221 pTimer->inUse = TIMER::free;
00222 pTimer->PMhwnd = 0;
00223 pTimer->PMid = 0;
00224 }
00225
00226 LeaveCriticalSection();
00227 }
00228
00229
00230
00231
00232 UINT WIN32API SetTimer (HWND hwnd, UINT id, UINT timeout, TIMERPROC proc)
00233 {
00234 UINT rc;
00235
00236 dprintf(("USER32: SetTimer %x %d %d %08lx", hwnd, id, timeout, (LONG)proc));
00237
00238 rc = TIMER_SetTimer (hwnd, id, timeout, proc, FALSE);
00239 return (rc);
00240 }
00241
00242
00243
00244
00245 UINT WIN32API SetSystemTimer (HWND hwnd, UINT id, UINT timeout, TIMERPROC proc)
00246 {
00247 UINT rc;
00248
00249 dprintf(("USER32: SetSystemTimer %04x %d %d %08lx", hwnd, id, timeout, (LONG)proc));
00250
00251 rc = TIMER_SetTimer (hwnd, id, timeout, proc, TRUE);
00252 return (rc);
00253 }
00254
00255
00256
00257
00258 BOOL WIN32API KillTimer (HWND hwnd, UINT id)
00259 {
00260 BOOL rc;
00261
00262 dprintf(("USER32: KillTimer %x %d", hwnd, id));
00263
00264 rc = TIMER_KillTimer (hwnd, id, FALSE);
00265 return (rc);
00266 }
00267
00268
00269
00270
00271 BOOL WIN32API KillSystemTimer (HWND hwnd, UINT id)
00272 {
00273 BOOL rc;
00274
00275 dprintf(("USER32: KillSystemTimer %x %d", hwnd, id));
00276
00277 rc = TIMER_KillTimer (hwnd, id, TRUE);
00278 return (rc);
00279 }
00280