Ignore:
Timestamp:
Sep 15, 2001, 11:28:23 AM (24 years ago)
Author:
sandervl
Message:

wine update

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 $ */
    21/*
    32 * Implementation of CLSID_SystemClock.
    43 *
    5  * FIXME - stub.
     4 * FIXME - not tested yet.
    65 *
    76 * hidenori@a2.ctktv.ne.jp
     
    1312#include "winbase.h"
    1413#include "wingdi.h"
     14#include "winuser.h"
    1515#include "winerror.h"
    1616#include "wine/obj_base.h"
     
    2525
    2626
     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
     34static 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
     50static 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
     67static 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
     114static
     115DWORD 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
     166quitthread:
     167        return 0;
     168}
     169
     170/****************************************************************************/
     171
    27172static HRESULT WINAPI
    28173IReferenceClock_fnQueryInterface(IReferenceClock* iface,REFIID riid,void** ppobj)
    29174{
    30     CSystemClock_THIS(iface,refclk);
    31 
    32     TRACE("(%p)->()\n",This);
    33 
    34     return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
     175        CSystemClock_THIS(iface,refclk);
     176
     177        TRACE("(%p)->()\n",This);
     178
     179        return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
    35180}
    36181
     
    38183IReferenceClock_fnAddRef(IReferenceClock* iface)
    39184{
    40     CSystemClock_THIS(iface,refclk);
    41 
    42     TRACE("(%p)->()\n",This);
    43 
    44     return IUnknown_AddRef(This->unk.punkControl);
     185        CSystemClock_THIS(iface,refclk);
     186
     187        TRACE("(%p)->()\n",This);
     188
     189        return IUnknown_AddRef(This->unk.punkControl);
    45190}
    46191
     
    48193IReferenceClock_fnRelease(IReferenceClock* iface)
    49194{
    50     CSystemClock_THIS(iface,refclk);
    51 
    52     TRACE("(%p)->()\n",This);
    53 
    54     return IUnknown_Release(This->unk.punkControl);
     195        CSystemClock_THIS(iface,refclk);
     196
     197        TRACE("(%p)->()\n",This);
     198
     199        return IUnknown_Release(This->unk.punkControl);
    55200}
    56201
     
    58203IReferenceClock_fnGetTime(IReferenceClock* iface,REFERENCE_TIME* prtTime)
    59204{
    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;
    64225}
    65226
     
    67228IReferenceClock_fnAdviseTime(IReferenceClock* iface,REFERENCE_TIME rtBase,REFERENCE_TIME rtStream,HEVENT hEvent,DWORD_PTR* pdwAdvCookie)
    68229{
    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;
     279err:
     280        LeaveCriticalSection( &This->m_csClock );
     281
     282        return hr;
    73283}
    74284
     
    76286IReferenceClock_fnAdvisePeriodic(IReferenceClock* iface,REFERENCE_TIME rtStart,REFERENCE_TIME rtPeriod,HSEMAPHORE hSemaphore,DWORD_PTR* pdwAdvCookie)
    77287{
    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;
     326err:
     327        LeaveCriticalSection( &This->m_csClock );
     328
     329        return hr;
    82330}
    83331
     
    85333IReferenceClock_fnUnadvise(IReferenceClock* iface,DWORD_PTR dwAdvCookie)
    86334{
    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;
    91351}
    92352
    93353static ICOM_VTABLE(IReferenceClock) irefclk =
    94354{
    95     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    96     /* IUnknown fields */
    97     IReferenceClock_fnQueryInterface,
    98     IReferenceClock_fnAddRef,
    99     IReferenceClock_fnRelease,
    100     /* IReferenceClock fields */
    101     IReferenceClock_fnGetTime,
    102     IReferenceClock_fnAdviseTime,
    103     IReferenceClock_fnAdvisePeriodic,
    104     IReferenceClock_fnUnadvise,
     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,
    105365};
    106366
    107367
    108 void CSystemClock_InitIReferenceClock( CSystemClock* psc )
    109 {
    110     TRACE("(%p)\n",psc);
    111     ICOM_VTBL(&psc->refclk) = &irefclk;
    112 }
     368HRESULT 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
     414err:
     415        DeleteCriticalSection( &psc->m_csClock );
     416        return E_FAIL;
     417}
     418
     419void 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.