Changeset 6710 for trunk/src/quartz/irclock.c
- Timestamp:
- Sep 15, 2001, 11:28:23 AM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/quartz/irclock.c
r6649 r6710 1 /* $Id: irclock.c,v 1.3 2001-09-05 13:36:37 bird Exp $ */2 1 /* 3 2 * Implementation of CLSID_SystemClock. 4 3 * 5 * FIXME - stub.4 * FIXME - not tested yet. 6 5 * 7 6 * hidenori@a2.ctktv.ne.jp … … 13 12 #include "winbase.h" 14 13 #include "wingdi.h" 14 #include "winuser.h" 15 15 #include "winerror.h" 16 16 #include "wine/obj_base.h" … … 25 25 26 26 27 #define QUARTZ_MSG_ADDTIMER (WM_APP+0) 28 #define QUARTZ_MSG_REMOVETIMER (WM_APP+1) 29 #define QUARTZ_MSG_EXITTHREAD (WM_APP+2) 30 31 32 /****************************************************************************/ 33 34 static QUARTZ_TimerEntry* IReferenceClock_AllocTimerEntry(CSystemClock* This) 35 { 36 QUARTZ_TimerEntry* pEntry; 37 DWORD dw; 38 39 pEntry = &This->m_timerEntries[0]; 40 for ( dw = 0; dw < WINE_QUARTZ_SYSCLOCK_TIMER_MAX; dw++ ) 41 { 42 if ( pEntry->hEvent == (HANDLE)NULL ) 43 return pEntry; 44 pEntry ++; 45 } 46 47 return NULL; 48 } 49 50 static QUARTZ_TimerEntry* IReferenceClock_SearchTimer(CSystemClock* This, DWORD dwAdvCookie) 51 { 52 QUARTZ_TimerEntry* pEntry; 53 DWORD dw; 54 55 pEntry = &This->m_timerEntries[0]; 56 for ( dw = 0; dw < WINE_QUARTZ_SYSCLOCK_TIMER_MAX; dw++ ) 57 { 58 if ( pEntry->hEvent != (HANDLE)NULL && 59 pEntry->dwAdvCookie == dwAdvCookie ) 60 return pEntry; 61 pEntry ++; 62 } 63 64 return NULL; 65 } 66 67 static void IReferenceClock_OnTimerUpdated(CSystemClock* This) 68 { 69 QUARTZ_TimerEntry* pEntry; 70 REFERENCE_TIME rtCur; 71 REFERENCE_TIME rtSignal; 72 REFERENCE_TIME rtCount; 73 HRESULT hr; 74 LONG lCount; 75 DWORD dw; 76 77 hr = IReferenceClock_GetTime((IReferenceClock*)(&This->refclk),&rtCur); 78 if ( hr != NOERROR ) 79 return; 80 81 pEntry = &This->m_timerEntries[0]; 82 for ( dw = 0; dw < WINE_QUARTZ_SYSCLOCK_TIMER_MAX; dw++ ) 83 { 84 if ( pEntry->hEvent != (HANDLE)NULL ) 85 { 86 rtSignal = pEntry->rtStart + pEntry->rtInterval; 87 if ( rtCur >= rtSignal ) 88 { 89 if ( pEntry->fPeriodic ) 90 { 91 rtCount = ((rtCur - pEntry->rtStart) / pEntry->rtInterval); 92 lCount = ( rtCount > (REFERENCE_TIME)0x7fffffff ) ? 93 (LONG)0x7fffffff : (LONG)rtCount; 94 if ( !ReleaseSemaphore( pEntry->hEvent, lCount, NULL ) ) 95 { 96 while ( lCount > 0 ) 97 { 98 if ( !ReleaseSemaphore( pEntry->hEvent, 1, NULL ) ) 99 break; 100 } 101 } 102 } 103 else 104 { 105 SetEvent( pEntry->hEvent ); 106 pEntry->hEvent = (HANDLE)NULL; 107 } 108 } 109 } 110 pEntry ++; 111 } 112 } 113 114 static 115 DWORD WINAPI IReferenceClock_TimerEntry( LPVOID lpvParam ) 116 { 117 CSystemClock* This = (CSystemClock*)lpvParam; 118 MSG msg; 119 DWORD dwRes; 120 121 /* initialize the message queue. */ 122 PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_NOREMOVE ); 123 /* resume the owner thread. */ 124 SetEvent( This->m_hEventInit ); 125 126 /* message loop. */ 127 while ( 1 ) 128 { 129 dwRes = MsgWaitForMultipleObjects( 130 0, NULL, FALSE, 131 INFINITE, /* FIXME */ 132 QS_ALLEVENTS ); 133 134 EnterCriticalSection( &This->m_csClock ); 135 IReferenceClock_OnTimerUpdated(This); 136 LeaveCriticalSection( &This->m_csClock ); 137 138 while ( PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_REMOVE ) ) 139 { 140 if ( msg.message == WM_QUIT ) 141 goto quitthread; 142 143 if ( msg.hwnd != (HWND)NULL ) 144 { 145 TranslateMessage( &msg ); 146 DispatchMessageA( &msg ); 147 } 148 else 149 { 150 switch ( msg.message ) 151 { 152 case QUARTZ_MSG_ADDTIMER: 153 case QUARTZ_MSG_REMOVETIMER: 154 break; 155 case QUARTZ_MSG_EXITTHREAD: 156 PostQuitMessage(0); 157 break; 158 default: 159 FIXME( "invalid message %04u\n", (unsigned)msg.message ); 160 break; 161 } 162 } 163 } 164 } 165 166 quitthread: 167 return 0; 168 } 169 170 /****************************************************************************/ 171 27 172 static HRESULT WINAPI 28 173 IReferenceClock_fnQueryInterface(IReferenceClock* iface,REFIID riid,void** ppobj) 29 174 { 30 31 32 33 34 175 CSystemClock_THIS(iface,refclk); 176 177 TRACE("(%p)->()\n",This); 178 179 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); 35 180 } 36 181 … … 38 183 IReferenceClock_fnAddRef(IReferenceClock* iface) 39 184 { 40 41 42 43 44 185 CSystemClock_THIS(iface,refclk); 186 187 TRACE("(%p)->()\n",This); 188 189 return IUnknown_AddRef(This->unk.punkControl); 45 190 } 46 191 … … 48 193 IReferenceClock_fnRelease(IReferenceClock* iface) 49 194 { 50 51 52 53 54 195 CSystemClock_THIS(iface,refclk); 196 197 TRACE("(%p)->()\n",This); 198 199 return IUnknown_Release(This->unk.punkControl); 55 200 } 56 201 … … 58 203 IReferenceClock_fnGetTime(IReferenceClock* iface,REFERENCE_TIME* prtTime) 59 204 { 60 CSystemClock_THIS(iface,refclk); 61 62 FIXME( "(%p)->() stub!\n", This ); 63 return E_NOTIMPL; 205 CSystemClock_THIS(iface,refclk); 206 DWORD dwTimeCur; 207 208 TRACE( "(%p)->(%p)\n", This, prtTime ); 209 210 if ( prtTime == NULL ) 211 return E_POINTER; 212 213 EnterCriticalSection( &This->m_csClock ); 214 215 dwTimeCur = GetTickCount(); 216 This->m_rtLast += (REFERENCE_TIME)(DWORD)(dwTimeCur - This->m_dwTimeLast); 217 218 This->m_dwTimeLast = dwTimeCur; 219 220 *prtTime = This->m_dwTimeLast; 221 222 LeaveCriticalSection( &This->m_csClock ); 223 224 return NOERROR; 64 225 } 65 226 … … 67 228 IReferenceClock_fnAdviseTime(IReferenceClock* iface,REFERENCE_TIME rtBase,REFERENCE_TIME rtStream,HEVENT hEvent,DWORD_PTR* pdwAdvCookie) 68 229 { 69 CSystemClock_THIS(iface,refclk); 70 71 FIXME( "(%p)->() stub!\n", This ); 72 return E_NOTIMPL; 230 CSystemClock_THIS(iface,refclk); 231 QUARTZ_TimerEntry* pEntry; 232 HRESULT hr; 233 REFERENCE_TIME rtCur; 234 235 TRACE( "(%p)->()\n", This ); 236 237 if ( pdwAdvCookie == NULL ) 238 return E_POINTER; 239 if ( hEvent == (HANDLE)NULL ) 240 return E_INVALIDARG; 241 242 EnterCriticalSection( &This->m_csClock ); 243 244 *pdwAdvCookie = (DWORD_PTR)(This->m_dwAdvCookieNext ++); 245 246 hr = IReferenceClock_GetTime(iface,&rtCur); 247 if ( hr != NOERROR ) 248 goto err; 249 if ( rtCur >= (rtBase+rtStream) ) 250 { 251 SetEvent(hEvent); 252 hr = NOERROR; 253 goto err; 254 } 255 256 pEntry = IReferenceClock_AllocTimerEntry(This); 257 if ( pEntry == NULL ) 258 { 259 hr = E_FAIL; 260 goto err; 261 } 262 263 if ( !PostThreadMessageA( 264 This->m_idThreadTimer, 265 QUARTZ_MSG_ADDTIMER, 266 0, 0 ) ) 267 { 268 hr = E_FAIL; 269 goto err; 270 } 271 272 pEntry->dwAdvCookie = *pdwAdvCookie; 273 pEntry->fPeriodic = FALSE; 274 pEntry->hEvent = hEvent; 275 pEntry->rtStart = rtBase; 276 pEntry->rtInterval = rtStream; 277 278 hr = NOERROR; 279 err: 280 LeaveCriticalSection( &This->m_csClock ); 281 282 return hr; 73 283 } 74 284 … … 76 286 IReferenceClock_fnAdvisePeriodic(IReferenceClock* iface,REFERENCE_TIME rtStart,REFERENCE_TIME rtPeriod,HSEMAPHORE hSemaphore,DWORD_PTR* pdwAdvCookie) 77 287 { 78 CSystemClock_THIS(iface,refclk); 79 80 FIXME( "(%p)->() stub!\n", This ); 81 return E_NOTIMPL; 288 CSystemClock_THIS(iface,refclk); 289 QUARTZ_TimerEntry* pEntry; 290 HRESULT hr; 291 292 TRACE( "(%p)->()\n", This ); 293 294 if ( pdwAdvCookie == NULL ) 295 return E_POINTER; 296 if ( hSemaphore == (HSEMAPHORE)NULL ) 297 return E_INVALIDARG; 298 299 EnterCriticalSection( &This->m_csClock ); 300 301 *pdwAdvCookie = (DWORD_PTR)(This->m_dwAdvCookieNext ++); 302 303 pEntry = IReferenceClock_AllocTimerEntry(This); 304 if ( pEntry == NULL ) 305 { 306 hr = E_FAIL; 307 goto err; 308 } 309 310 if ( !PostThreadMessageA( 311 This->m_idThreadTimer, 312 QUARTZ_MSG_ADDTIMER, 313 0, 0 ) ) 314 { 315 hr = E_FAIL; 316 goto err; 317 } 318 319 pEntry->dwAdvCookie = *pdwAdvCookie; 320 pEntry->fPeriodic = TRUE; 321 pEntry->hEvent = (HANDLE)hSemaphore; 322 pEntry->rtStart = rtStart; 323 pEntry->rtInterval = rtPeriod; 324 325 hr = NOERROR; 326 err: 327 LeaveCriticalSection( &This->m_csClock ); 328 329 return hr; 82 330 } 83 331 … … 85 333 IReferenceClock_fnUnadvise(IReferenceClock* iface,DWORD_PTR dwAdvCookie) 86 334 { 87 CSystemClock_THIS(iface,refclk); 88 89 FIXME( "(%p)->() stub!\n", This ); 90 return E_NOTIMPL; 335 CSystemClock_THIS(iface,refclk); 336 QUARTZ_TimerEntry* pEntry; 337 338 TRACE( "(%p)->(%lu)\n", This, (DWORD)dwAdvCookie ); 339 340 EnterCriticalSection( &This->m_csClock ); 341 342 pEntry = IReferenceClock_SearchTimer(This,(DWORD)dwAdvCookie); 343 if ( pEntry != NULL ) 344 { 345 pEntry->hEvent = (HANDLE)NULL; 346 } 347 348 LeaveCriticalSection( &This->m_csClock ); 349 350 return NOERROR; 91 351 } 92 352 93 353 static ICOM_VTABLE(IReferenceClock) irefclk = 94 354 { 95 96 97 98 99 100 101 102 103 104 355 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE 356 /* IUnknown fields */ 357 IReferenceClock_fnQueryInterface, 358 IReferenceClock_fnAddRef, 359 IReferenceClock_fnRelease, 360 /* IReferenceClock fields */ 361 IReferenceClock_fnGetTime, 362 IReferenceClock_fnAdviseTime, 363 IReferenceClock_fnAdvisePeriodic, 364 IReferenceClock_fnUnadvise, 105 365 }; 106 366 107 367 108 void CSystemClock_InitIReferenceClock( CSystemClock* psc ) 109 { 110 TRACE("(%p)\n",psc); 111 ICOM_VTBL(&psc->refclk) = &irefclk; 112 } 368 HRESULT CSystemClock_InitIReferenceClock( CSystemClock* psc ) 369 { 370 HANDLE hEvents[2]; 371 372 TRACE("(%p)\n",psc); 373 ICOM_VTBL(&psc->refclk) = &irefclk; 374 375 InitializeCriticalSection( &psc->m_csClock ); 376 psc->m_dwTimeLast = GetTickCount(); 377 psc->m_rtLast = (REFERENCE_TIME)0; 378 psc->m_hThreadTimer = (HANDLE)NULL; 379 psc->m_hEventInit = (HANDLE)NULL; 380 psc->m_idThreadTimer = 0; 381 psc->m_dwAdvCookieNext = 1; 382 ZeroMemory( psc->m_timerEntries, sizeof(psc->m_timerEntries) ); 383 384 psc->m_hEventInit = CreateEventA( NULL, TRUE, FALSE, NULL ); 385 if ( psc->m_hEventInit == (HANDLE)NULL ) 386 goto err; 387 388 psc->m_hThreadTimer = CreateThread( 389 NULL, 0, 390 IReferenceClock_TimerEntry, 391 psc, 0, &psc->m_idThreadTimer ); 392 393 if ( psc->m_hThreadTimer == (HANDLE)NULL ) 394 { 395 CloseHandle( psc->m_hEventInit ); 396 psc->m_hEventInit = (HANDLE)NULL; 397 goto err; 398 } 399 400 hEvents[0] = psc->m_hEventInit; 401 hEvents[1] = psc->m_hThreadTimer; 402 if ( WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE ) 403 != WAIT_OBJECT_0 ) 404 { 405 CloseHandle( psc->m_hEventInit ); 406 psc->m_hEventInit = (HANDLE)NULL; 407 CloseHandle( psc->m_hThreadTimer ); 408 psc->m_hThreadTimer = (HANDLE)NULL; 409 goto err; 410 } 411 412 return NOERROR; 413 414 err: 415 DeleteCriticalSection( &psc->m_csClock ); 416 return E_FAIL; 417 } 418 419 void CSystemClock_UninitIReferenceClock( CSystemClock* psc ) 420 { 421 TRACE("(%p)\n",psc); 422 423 if ( psc->m_hThreadTimer != (HANDLE)NULL ) 424 { 425 if ( PostThreadMessageA( 426 psc->m_idThreadTimer, 427 QUARTZ_MSG_EXITTHREAD, 428 0, 0 ) ) 429 { 430 WaitForSingleObject( psc->m_hThreadTimer, INFINITE ); 431 } 432 CloseHandle( psc->m_hThreadTimer ); 433 psc->m_hThreadTimer = (HANDLE)NULL; 434 } 435 436 DeleteCriticalSection( &psc->m_csClock ); 437 }
Note:
See TracChangeset
for help on using the changeset viewer.