📄 speventq.h
字号:
return hr;
}
/****************************************************************************
* CSpEventSource::_GetNotifyEventHandle *
*---------------------------------------*
* Description:
*
* Returns:
*
********************************************************************* RAL ***/
inline HANDLE CSpEventSource::_GetNotifyEventHandle()
{
HANDLE h = NULL;
SPDBG_FUNC("CSpEventSource::_GetNotifyEventHandle");
m_NotifyObjChangeCrit.Lock();
if (!m_cpNotifySink)
{
_SetNotifyWin32Event();
}
if (m_cpEventTranslator)
{
h = m_cpEventTranslator->GetEventHandle();
}
m_NotifyObjChangeCrit.Unlock();
return h;
}
inline HRESULT CSpEventSource::_SetInterest( ULONGLONG ullEventInterest, ULONGLONG ullQueuedInterest )
{
HRESULT hr = S_OK;
m_pParent->Lock();
if(ullEventInterest && SPFEI_FLAGCHECK != (ullEventInterest & SPFEI_FLAGCHECK))
{
hr = E_INVALIDARG;
}
else if(ullQueuedInterest && SPFEI_FLAGCHECK != (ullQueuedInterest & SPFEI_FLAGCHECK))
{
hr = E_INVALIDARG;
}
else if ((ullQueuedInterest | ullEventInterest) != ullEventInterest)
{
hr = E_INVALIDARG;
}
else
{
m_ullEventInterest = ullEventInterest;
m_ullQueuedInterest = ullQueuedInterest;
}
m_pParent->Unlock();
return hr;
}
//
// Same as AddEvents except: No param validation, and caller must take the critical section
// prior to calling.
//
inline HRESULT CSpEventSource::_AddEvents( const SPEVENT* pEventArray, ULONG ulCount )
{
HRESULT hr = S_OK;
for( ULONG i = 0; i < ulCount && SUCCEEDED(hr = _AddEvent(pEventArray[i])); ++i ) {}
return hr;
}
inline HRESULT CSpEventSource::_AddEvent(const SPEVENT & Event)
{
SPDBG_ASSERT(Event.eEventId < 64);
SPDBG_ASSERT(Event.elParamType == SPET_LPARAM_IS_UNDEFINED ||
Event.elParamType == SPET_LPARAM_IS_TOKEN ||
Event.elParamType == SPET_LPARAM_IS_OBJECT ||
Event.elParamType == SPET_LPARAM_IS_POINTER ||
Event.elParamType == SPET_LPARAM_IS_STRING);
#ifdef _DEBUG
if (Event.eEventId == SPEI_VOICE_CHANGE)
{
SPDBG_ASSERT(Event.elParamType == SPET_LPARAM_IS_TOKEN);
}
else if (Event.eEventId == SPEI_RECOGNITION || Event.eEventId == SPEI_FALSE_RECOGNITION || Event.eEventId == SPEI_HYPOTHESIS)
{
SPDBG_ASSERT(Event.elParamType == SPET_LPARAM_IS_OBJECT);
}
else if (Event.eEventId ==SPEI_REQUEST_UI || Event.eEventId == SPEI_TTS_BOOKMARK)
{
SPDBG_ASSERT(Event.elParamType == SPET_LPARAM_IS_STRING);
}
#endif
if ( (1i64 << Event.eEventId) & m_ullEventInterest )
{
CSpEventNode *pNode = m_FreeList.RemoveHead();
if (pNode == NULL)
{
pNode = new CSpEventNode();
if (pNode == NULL)
{
return E_OUTOFMEMORY;
}
}
pNode->CopyFrom(&Event);
m_PendingList.InsertSorted(pNode);
}
return S_OK;
}
inline HRESULT CSpEventSource::
_DeserializeAndAddEvent(const BYTE *pBuffer, ULONG * pcbUsed)
{
HRESULT hr = S_OK;
const SPEVENT * pSrcEvent = (const SPEVENT *)pBuffer;
SPDBG_ASSERT(pSrcEvent->eEventId < 64);
if ( (1i64 << pSrcEvent->eEventId) & m_ullEventInterest )
{
CSpEventNode *pNode = m_FreeList.RemoveHead();
if (pNode == NULL)
{
pNode = new CSpEventNode();
if (pNode == NULL)
{
hr = E_OUTOFMEMORY;
}
}
if (SUCCEEDED(hr))
{
hr = pNode->Deserialize(((const SPSERIALIZEDEVENT64 *)(pBuffer)), pcbUsed);
if (SUCCEEDED(hr))
{
m_PendingList.InsertSorted(pNode);
}
else
{
m_FreeList.InsertHead(pNode);
}
}
}
else
{
// WCE compiler does not work propertly with template
#ifndef _WIN32_WCE
*pcbUsed = SpEventSerializeSize<SPSERIALIZEDEVENT64>(pSrcEvent);
#else
*pcbUsed = SpEventSerializeSize(pSrcEvent, sizeof(SPSERIALIZEDEVENT64));
#endif
}
return hr;
}
inline HRESULT CSpEventSource::_GetEvents( ULONG ulCount, SPEVENT* pEventArray, ULONG *pulFetched )
{
HRESULT hr = S_OK;
m_pParent->Lock();
if( SPIsBadWritePtr( pEventArray, sizeof( SPEVENT ) * ulCount ) ||
SP_IS_BAD_OPTIONAL_WRITE_PTR(pulFetched) )
{
hr = E_INVALIDARG;
}
else
{
ULONG ulCopied = 0;
ULONG ulRemaining = ulCount;
CSpEventNode * pCur = m_CompletedList.m_pHead;
CSpEventNode * pLastCopied = NULL;
while (ulRemaining && pCur)
{
pCur->Detach(pEventArray + ulCopied);
pLastCopied = pCur;
ulCopied++;
pCur = pCur->m_pNext;
ulRemaining--;
}
if (ulCopied)
{
if (m_FreeList.m_pHead == NULL)
{
m_FreeList.m_pTail = pLastCopied;
}
pLastCopied->m_pNext = m_FreeList.m_pHead;
m_FreeList.m_pHead = m_CompletedList.m_pHead;
m_CompletedList.m_pHead = pCur;
m_CompletedList.m_cElements -= ulCopied;
m_FreeList.m_cElements += ulCopied;
}
if (ulCopied < ulCount)
{
hr = S_FALSE;
}
if (pulFetched)
{
*pulFetched = ulCopied;
}
}
m_pParent->Unlock();
return hr;
}
inline HRESULT CSpEventSource::_GetInfo( SPEVENTSOURCEINFO * pInfo )
{
HRESULT hr = S_OK;
m_pParent->Lock();
if( SP_IS_BAD_WRITE_PTR( pInfo ) )
{
hr = E_POINTER;
}
else
{
pInfo->ulCount = m_CompletedList.GetCount();
pInfo->ullEventInterest = m_ullEventInterest;
pInfo->ullQueuedInterest= m_ullQueuedInterest;
}
m_pParent->Unlock();
return hr;
}
//
// The caller must call this function with the critical section owned
//
inline HRESULT CSpEventSource::_CompleteEvents( ULONGLONG ullPos )
{
HRESULT hr = S_OK;
if (m_PendingList.m_pHead && m_PendingList.m_pHead->ullAudioStreamOffset <= ullPos)
{
BOOL bNotify = FALSE;
while (m_PendingList.m_pHead &&
m_PendingList.m_pHead->ullAudioStreamOffset <= ullPos)
{
CSpEventNode *pNode = m_PendingList.RemoveHead();
if(pNode->ulStreamNum != m_ulStreamNum)
{
m_ulStreamNum = pNode->ulStreamNum;
}
if ( (1i64 << pNode->eEventId) & m_ullEventInterest )
{
bNotify = TRUE;
//
// NOTE: If we're forwarding events to an event sink then we'll only
// pay attention to the Interest flags. If we're going to notify, then
// we'll only queue completed events that the user has explicitly asked
// us to store as completed events.
//
if ( (1i64 << pNode->eEventId) & m_ullQueuedInterest )
{
m_CompletedList.InsertSorted(pNode);
}
else
{
pNode->Clear();
m_FreeList.InsertHead(pNode);
}
}
else
{
pNode->Clear();
m_FreeList.InsertHead(pNode);
}
}
if (bNotify && m_cpNotifySink)
{
hr = m_cpNotifySink->Notify();
}
}
return hr;
};
inline void CSpEventSource::_MoveAllToFreeList(CSpEventList * pList)
{
CSpEventNode * pNode;
while ((pNode = pList->RemoveHead()) != NULL)
{
pNode->Clear();
m_FreeList.InsertHead(pNode);
}
}
inline void CSpEventSource::_RemoveAllEvents( )
{
m_pParent->Lock();
_MoveAllToFreeList(&m_CompletedList);
_MoveAllToFreeList(&m_PendingList);
m_pParent->Unlock();
}
inline HRESULT CSpEventSource::_GetStreamNumber(const ULONGLONG ullAudioOffset, ULONG *pulStreamNum)
{
CSpEventNode *pNode = m_PendingList.m_pHead;
*pulStreamNum = m_ulStreamNum;
for(;pNode && pNode->ullAudioStreamOffset <= ullAudioOffset; pNode = pNode->m_pNext)
{
*pulStreamNum = pNode->ulStreamNum;
}
return S_OK;
}
#endif //--- This must be the last line in this file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -