Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

timer.cpp

Go to the documentation of this file.
00001 /* $Id: timer.cpp,v 1.14 2001/07/09 18:09:13 sandervl Exp $ */
00002 
00003 /*
00004  * timer functions for USER32
00005  *
00006  * Copyright 1993 Alexandre Julliard
00007  * Copyright 1999 Daniela Engert (dani@ngrt.de)
00008  *
00009  * Project Odin Software License can be found in LICENSE.TXT
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  /* for SetSystemTimer */
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)  /* no matching timer found */
00079       return (FALSE);  /* forward message */
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)  /* no matching timer found */
00099         return (FALSE);  /* forward message */
00100 
00101     pMsg->mp2 = MPFROMLONG (TRUE);   /* mark for Win32 */
00102     if (!pTimer->proc)
00103         return (FALSE);  /* forward message */
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     /* Check if there's already a timer with the same hwnd and id */
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)  /* no matching timer found */
00138     {
00139         /* Find a free timer */
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         /* Add the timer */
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     /* Find the timer */
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     /* Delete the timer */
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  *           SetTimer32   (USER32.511)
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  *           SetSystemTimer32   (USER32.509)
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  *           KillTimer32   (USER32.354)
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  *           KillSystemTimer32   (USER32.353)
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 

Generated on Wed Jan 23 23:17:43 2002 for ODIN-user32 by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001