eventmgr.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:26k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: eventmgr.cpp,v 1.4.8.1 2004/07/09 02:05:57 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #if defined(HELIX_FEATURE_EVENTMANAGER)
  50. // include
  51. #include "hxtypes.h"
  52. #include "hxcom.h"
  53. #include "hxresult.h"
  54. #include "ihxpckts.h"
  55. #include "hxcomm.h"
  56. #include "hxengin.h"
  57. #include "hxinter.h"
  58. // pncont
  59. #include "hxslist.h"
  60. #include "hxmap.h"
  61. // rmacore
  62. #include "hxcbobj.h"
  63. #include "eventmgr.h"
  64. // pndebug
  65. #include "hxheap.h"
  66. #ifdef _DEBUG
  67. #undef HX_THIS_FILE             
  68. static const char HX_THIS_FILE[] = __FILE__;
  69. #endif
  70. CRendererEventManager::CRendererEventManager(IUnknown* pContext)
  71. {
  72.     m_lRefCount        = 0;
  73.     m_pContext         = pContext;
  74.     m_pScheduler       = NULL;
  75.     m_pSinkList        = NULL;
  76.     m_pSinkToFilterMap = NULL;
  77.     m_pCallback        = NULL;
  78.     m_pEventQueue      = NULL;
  79.     m_pEventQueueMutex = NULL;
  80.     if (m_pContext)
  81.     {
  82.         // AddRef the context
  83.         m_pContext->AddRef();
  84.         // QI for IHXCommonClassFactory
  85.         IHXCommonClassFactory* pFactory = NULL;
  86.         m_pContext->QueryInterface(IID_IHXCommonClassFactory,
  87.                                    (void**) &pFactory);
  88.         if (pFactory)
  89.         {
  90.             // Create a mutex
  91.             pFactory->CreateInstance(CLSID_IHXMutex,
  92.                                      (void**) &m_pEventQueueMutex);
  93.         }
  94.         HX_RELEASE(pFactory);
  95.     }
  96. }
  97. CRendererEventManager::~CRendererEventManager()
  98. {
  99.     Close();
  100. }
  101. STDMETHODIMP CRendererEventManager::QueryInterface(REFIID riid, void** ppvObj)
  102. {
  103.     HX_RESULT retVal = HXR_OK;
  104.     if (ppvObj)
  105.     {
  106.         QInterfaceList qiList[] =
  107.             {
  108.                 { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXEventManager*)this },
  109.                 { GET_IIDHANDLE(IID_IHXEventManager), (IHXEventManager*)this },
  110.                 { GET_IIDHANDLE(IID_IHXCallback), (IHXCallback*)this },
  111.             };
  112.         
  113.         retVal = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  114.     }
  115.     else
  116.     {
  117.         retVal = HXR_FAIL;
  118.     }
  119.     return retVal;
  120. }
  121. STDMETHODIMP_(ULONG32) CRendererEventManager::AddRef()
  122. {
  123.     return InterlockedIncrement(&m_lRefCount);
  124. }
  125. STDMETHODIMP_(ULONG32) CRendererEventManager::Release()
  126. {
  127.     if (InterlockedDecrement(&m_lRefCount) > 0)
  128.     {
  129.         return m_lRefCount;
  130.     }
  131.     delete this;
  132.     return 0;
  133. }
  134. STDMETHODIMP CRendererEventManager::AddEventSink(IHXEventSink* pSink)
  135. {
  136.     HX_RESULT retVal = HXR_FAIL;
  137.     if (pSink)
  138.     {
  139.         // Do we have a list?
  140.         if (!m_pSinkList)
  141.         {
  142.             m_pSinkList = new CHXSimpleList();
  143.         }
  144.         if (m_pSinkList)
  145.         {
  146.             // Clear the return value
  147.             retVal = HXR_OK;
  148.             // Make sure this sink is not already on the list
  149.             if (!IsSinkInList(pSink))
  150.             {
  151.                 // AddRef before we put it on the list
  152.                 pSink->AddRef();
  153.                 // Now put this sink on the tail of the list
  154.                 m_pSinkList->AddTail((void*) pSink);
  155.                 // Add an NULL entry for this sink in the map
  156.                 if (!m_pSinkToFilterMap)
  157.                 {
  158.                     m_pSinkToFilterMap = new CHXMapPtrToPtr();
  159.                 }
  160.                 if (m_pSinkToFilterMap)
  161.                 {
  162.                     m_pSinkToFilterMap->SetAt((void*) pSink, NULL);
  163.                 }
  164.             }
  165.         }
  166.     }
  167.     return retVal;
  168. }
  169. STDMETHODIMP CRendererEventManager::RemoveEventSink(IHXEventSink* pSink)
  170. {
  171.     HX_RESULT retVal = HXR_OK;
  172.     if (pSink && m_pSinkList && m_pSinkList->GetCount() > 0)
  173.     {
  174.         // Remove the sink's entry in the sink-to-filter map and
  175.         // release our ref on the filter
  176.         void* pVoid = NULL;
  177.         if (m_pSinkToFilterMap &&
  178.             m_pSinkToFilterMap->Lookup((void*) pSink, pVoid))
  179.         {
  180.             // Get the key value list
  181.             CHXSimpleList* pList = (CHXSimpleList*) pVoid;
  182.             // Clear this list
  183.             ClearSinkFilterList(pList);
  184.             // Delete the rule list
  185.             HX_DELETE(pList);
  186.             // Remove the entry from the sink-to-filter map
  187.             m_pSinkToFilterMap->RemoveKey((void*) pSink);
  188.         }
  189.         // Run through the sink list and release
  190.         // the list's ref on the sink
  191.         LISTPOSITION pos = m_pSinkList->GetHeadPosition();
  192.         while (pos)
  193.         {
  194.             IHXEventSink* pListSink =
  195.                 (IHXEventSink*) m_pSinkList->GetAt(pos);
  196.             if (pListSink && pListSink == pSink)
  197.             {
  198.                 m_pSinkList->RemoveAt(pos);
  199.                 HX_RELEASE(pListSink);
  200.                 break;
  201.             }
  202.             m_pSinkList->GetNext(pos);
  203.         }
  204.     }
  205.     return retVal;
  206. }
  207. STDMETHODIMP CRendererEventManager::AddEventSinkFilterRule(IHXEventSink* pSink,
  208.                                                            IHXValues*    pRule)
  209. {
  210.     HX_RESULT retVal = HXR_FAIL;
  211.     if (pSink && pRule && m_pSinkToFilterMap)
  212.     {
  213.         // Do we have an entry in the filter map? We definitely
  214.         // should, because it was initialized when the sink
  215.         // was added to the sink list. The entry can be NULL,
  216.         // but there has to be an entry.
  217.         void* pVoid = NULL;
  218.         if (m_pSinkToFilterMap->Lookup((void*) pSink, pVoid))
  219.         {
  220.             // Get the filter
  221.             CHXSimpleList* pFilter = (CHXSimpleList*) pVoid;
  222.             // If the filter is NULL, then that means
  223.             // we need to create the list and put it
  224.             // back into the map
  225.             if (!pFilter)
  226.             {
  227.                 pFilter = new CHXSimpleList();
  228.                 if (pFilter)
  229.                 {
  230.                     m_pSinkToFilterMap->SetAt((void*) pSink,
  231.                                               (void*) pFilter);
  232.                 }
  233.             }
  234.             if (pFilter)
  235.             {
  236.                 // Create the CEventSinkFilterRule object
  237.                 CEventSinkFilterRule* pRuleObj =
  238.                     new CEventSinkFilterRule(pRule);
  239.                 if (pRuleObj)
  240.                 {
  241.                     // Make sure this rule is not already in the list
  242.                     BOOL bPresent = FALSE;
  243.                     LISTPOSITION pos = pFilter->GetHeadPosition();
  244.                     while (pos)
  245.                     {
  246.                         CEventSinkFilterRule* pListRuleObj =
  247.                             (CEventSinkFilterRule*) pFilter->GetNext(pos);
  248.                         if (pListRuleObj &&
  249.                             pListRuleObj->Same(pRuleObj))
  250.                         {
  251.                             bPresent = TRUE;
  252.                             break;
  253.                         }
  254.                     }
  255.                     // Was the rule already present?
  256.                     if (!bPresent)
  257.                     {
  258.                         // It was NOT already present, so we
  259.                         // can append it to the list of rules
  260.                         pFilter->AddTail((void*) pRuleObj);
  261.                     }
  262.                     else
  263.                     {
  264.                         // It was already present, so we can
  265.                         // delete this object
  266.                         HX_DELETE(pRuleObj);
  267.                     }
  268.                     // Clear the return value
  269.                     retVal = HXR_OK;
  270.                 }
  271.             }
  272.         }
  273.     }
  274.     return retVal;
  275. }
  276. STDMETHODIMP CRendererEventManager::RemoveEventSinkFilterRule(IHXEventSink* pSink,
  277.                                                               IHXValues*    pRule)
  278. {
  279.     HX_RESULT retVal = HXR_FAIL;
  280.     if (pSink && pRule && m_pSinkToFilterMap)
  281.     {
  282.         // Do we have an entry in the filter map? We definitely
  283.         // should, because it was initialized when the sink
  284.         // was added to the sink list. The entry can be NULL,
  285.         // but there has to be an entry.
  286.         void* pVoid = NULL;
  287.         if (m_pSinkToFilterMap->Lookup((void*) pSink, pVoid))
  288.         {
  289.             // Get the filter
  290.             CHXSimpleList* pFilter = (CHXSimpleList*) pVoid;
  291.             // Do we have a filter for this sink yet?
  292.             if (pFilter)
  293.             {
  294.                 // Create a temp CEventSinkFilterRule object
  295.                 // just so we can use CEventSinkFilterRule::Same()
  296.                 CEventSinkFilterRule* pRuleObj =
  297.                     new CEventSinkFilterRule(pRule);
  298.                 if (pRuleObj)
  299.                 {
  300.                     // Find this rule in the list
  301.                     LISTPOSITION pos = pFilter->GetHeadPosition();
  302.                     while (pos)
  303.                     {
  304.                         CEventSinkFilterRule* pListRuleObj =
  305.                             (CEventSinkFilterRule*) pFilter->GetAt(pos);
  306.                         if (pListRuleObj &&
  307.                             pListRuleObj->Same(pRuleObj))
  308.                         {
  309.                             // Remove the rule from the list
  310.                             pFilter->RemoveAt(pos);
  311.                             // Delete the rule object
  312.                             HX_DELETE(pListRuleObj);
  313.                             // Jump out of the loop
  314.                             break;
  315.                         }
  316.                         else
  317.                         {
  318.                             pFilter->GetNext(pos);
  319.                         }
  320.                     }
  321.                     // Clear the return value
  322.                     retVal = HXR_OK;
  323.                 }
  324.                 // Delete the temporary rule
  325.                 HX_DELETE(pRuleObj);
  326.             }
  327.         }
  328.     }
  329.     return retVal;
  330. }
  331. STDMETHODIMP CRendererEventManager::FireEvent(IHXBuffer* pURLStr,
  332.                                               IHXBuffer* pFragmentStr,
  333.                                               IHXBuffer* pEventNameStr,
  334.                                               IHXValues* pOtherValues)
  335. {
  336.     HX_RESULT retVal = HXR_FAIL;
  337.     if (pURLStr && pEventNameStr)
  338.     {
  339.         // Do we have a scheduler interface?
  340.         if (!m_pScheduler && m_pContext)
  341.         {
  342.             // QI for IHXScheduler
  343.             m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler);
  344.         }
  345.         if (m_pScheduler)
  346.         {
  347.             // Do we have a callback?
  348.             if (!m_pCallback)
  349.             {
  350.                 // Create a callback object
  351.                 m_pCallback = new CHXGenericCallback((void*)this, (fGenericCBFunc)RendererEventCallback);
  352.                 if (m_pCallback)
  353.                 {
  354.                     m_pCallback->AddRef();
  355.                 }
  356.             }
  357.             if (m_pCallback)
  358.             {
  359.                 // Create the event object
  360.                 CRendererEvent* pEvent = new CRendererEvent(pURLStr,
  361.                                                             pFragmentStr,
  362.                                                             pEventNameStr,
  363.                                                             pOtherValues);
  364.                 if (pEvent)
  365.                 {
  366.                     // Do we have an event queue?
  367.                     if (!m_pEventQueue)
  368.                     {
  369.                         // Create an event queue
  370.                         m_pEventQueue = new CHXSimpleList();
  371.                     }
  372.                     if (m_pEventQueue)
  373.                     {
  374.                         // Lock the mutex
  375.                         if (m_pEventQueueMutex) m_pEventQueueMutex->Lock();
  376.                         // Put the event object on the queue
  377.                         m_pEventQueue->AddTail((void*) pEvent);
  378.                         // If we don't already have a callback scheduled
  379.                         // then schedule one
  380.                         if (!m_pCallback->GetPendingCallback())
  381.                         {
  382.                             m_pCallback->CallbackScheduled(m_pScheduler->RelativeEnter(m_pCallback, 0));
  383.                         }
  384.                         // Unlock the mutex
  385.                         if (m_pEventQueueMutex) m_pEventQueueMutex->Unlock();
  386.                         // Clear the return value
  387.                         retVal = HXR_OK;
  388.                     }
  389.                 }
  390.                 if (FAILED(retVal))
  391.                 {
  392.                     HX_DELETE(pEvent);
  393.                 }
  394.             }
  395.         }
  396.     }
  397.     return retVal;
  398. }
  399. STDMETHODIMP CRendererEventManager::Func()
  400. {
  401.     HX_RESULT retVal = HXR_OK;
  402.     // Lock the mutex
  403.     if (m_pEventQueueMutex) m_pEventQueueMutex->Lock();
  404.     // Fire off all the events in the event queue
  405.     if (m_pEventQueue && m_pEventQueue->GetCount() > 0)
  406.     {
  407.         LISTPOSITION pos = m_pEventQueue->GetHeadPosition();
  408.         while (pos)
  409.         {
  410.             // Get the event
  411.             CRendererEvent* pEvent =
  412.                 (CRendererEvent*) m_pEventQueue->GetNext(pos);
  413.             if (pEvent)
  414.             {
  415.                 // Loop through our lists and test each sink
  416.                 // to see if it should be passed this event
  417.                 //
  418.                 // XXXMEH - TODO - short-circuit the callback - if
  419.                 // we find out that there are no sinks registered for
  420.                 // this kind of event up front, then we shouldn't 
  421.                 // even fire the callback
  422.                 //
  423.                 if (m_pSinkList && m_pSinkList->GetCount() > 0)
  424.                 {
  425.                     LISTPOSITION pos = m_pSinkList->GetHeadPosition();
  426.                     while (pos)
  427.                     {
  428.                         IHXEventSink* pSink =
  429.                             (IHXEventSink*) m_pSinkList->GetNext(pos);
  430.                         if (ShouldSinkGetEvent(pSink, pEvent))
  431.                         {
  432.                             pEvent->Fire(pSink);
  433.                         }
  434.                     }
  435.                 }
  436.             }
  437.             // Now that we've processed the event,
  438.             // we can delete it
  439.             HX_DELETE(pEvent);
  440.         }
  441.         // Now remove everything from the queue
  442.         m_pEventQueue->RemoveAll();
  443.     }
  444.     // Unlock the mutex
  445.     if (m_pEventQueueMutex) m_pEventQueueMutex->Unlock();
  446.     return retVal;
  447. }
  448. STDMETHODIMP CRendererEventManager::Close()
  449. {
  450.     HX_RESULT retVal = HXR_OK;
  451.     // Cleanup all remaining callbacks
  452.     if (m_pCallback && m_pScheduler)
  453.     {
  454.         m_pScheduler->Remove(m_pCallback->GetPendingCallback());
  455.         m_pCallback->CallbackCanceled();
  456.     }
  457.     HX_RELEASE(m_pCallback);
  458.     HX_RELEASE(m_pScheduler);
  459.     HX_RELEASE(m_pContext);
  460.     ClearSinks();
  461.     HX_DELETE(m_pSinkList);
  462.     HX_DELETE(m_pSinkToFilterMap);
  463.     ClearEventQueue();
  464.     HX_DELETE(m_pEventQueue);
  465.     HX_RELEASE(m_pEventQueueMutex);
  466.     return retVal;
  467. }
  468. void CRendererEventManager::ClearSinks()
  469. {
  470.     if (m_pSinkToFilterMap)
  471.     {
  472.         // Run through the filter map and release each entry
  473.         POSITION pos = m_pSinkToFilterMap->GetStartPosition();
  474.         while (pos)
  475.         {
  476.             void* pKey   = NULL;
  477.             void* pEntry = NULL;
  478.             m_pSinkToFilterMap->GetNextAssoc(pos, pKey, pEntry);
  479.             if (pEntry)
  480.             {
  481.                 // Get the filter
  482.                 CHXSimpleList* pFilter = (CHXSimpleList*) pEntry;
  483.                 // Clear this list
  484.                 ClearSinkFilterList(pFilter);
  485.                 // Delete the rule list
  486.                 HX_DELETE(pFilter);
  487.             }
  488.         }
  489.         m_pSinkToFilterMap->RemoveAll();
  490.     }
  491.     if (m_pSinkList)
  492.     {
  493.         // Run through the list, releasing the sinks
  494.         LISTPOSITION pos = m_pSinkList->GetHeadPosition();
  495.         while (pos)
  496.         {
  497.             IHXEventSink* pSink = (IHXEventSink*) m_pSinkList->GetNext(pos);
  498.             HX_RELEASE(pSink);
  499.         }
  500.         m_pSinkList->RemoveAll();
  501.     }
  502. }
  503. BOOL CRendererEventManager::IsSinkInList(IHXEventSink* pSink)
  504. {
  505.     BOOL bRet = FALSE;
  506.     if (pSink && m_pSinkList)
  507.     {
  508.         LISTPOSITION pos = m_pSinkList->GetHeadPosition();
  509.         while (pos)
  510.         {
  511.             IHXEventSink* pListSink =
  512.                 (IHXEventSink*) m_pSinkList->GetNext(pos);
  513.             if (pListSink &&
  514.                 pListSink == pSink)
  515.             {
  516.                 bRet = TRUE;
  517.                 break;
  518.             }
  519.         }
  520.     }
  521.     return bRet;
  522. }
  523. void CRendererEventManager::ClearEventQueue()
  524. {
  525.     if (m_pEventQueue && m_pEventQueue->GetCount() > 0)
  526.     {
  527.         LISTPOSITION pos = m_pEventQueue->GetHeadPosition();
  528.         while (pos)
  529.         {
  530.             CRendererEvent* pEvent =
  531.                 (CRendererEvent*) m_pEventQueue->GetNext(pos);
  532.             HX_DELETE(pEvent);
  533.         }
  534.         m_pEventQueue->RemoveAll();
  535.     }
  536. }
  537. BOOL CRendererEventManager::ShouldSinkGetEvent(IHXEventSink*  pSink,
  538.                                                CRendererEvent* pEvent)
  539. {
  540.     BOOL bRet = FALSE;
  541.     if (pSink && pEvent && m_pSinkToFilterMap)
  542.     {
  543.         // Look up the filter for this sink
  544.         void* pVoid = NULL;
  545.         if (m_pSinkToFilterMap->Lookup((void*) pSink, pVoid))
  546.         {
  547.             // Get the filter
  548.             CHXSimpleList* pFilter = (CHXSimpleList*) pVoid;
  549.             // Check if the event passes the filter
  550.             bRet = PassFilter(pFilter, pEvent);
  551.         }
  552.     }
  553.     return bRet;
  554. }
  555. BOOL CRendererEventManager::PassFilter(CHXSimpleList*  pFilter,
  556.                                        CRendererEvent* pEvent)
  557. {
  558.     BOOL bRet = FALSE;
  559.     // Do we have a non-NULL filter?
  560.     if (pFilter)
  561.     {
  562.         if (pEvent)
  563.         {
  564.             // Loop through the rules until we find a rule
  565.             // that will allow this event to pass through
  566.             LISTPOSITION pos = pFilter->GetHeadPosition();
  567.             while (pos)
  568.             {
  569.                 CEventSinkFilterRule* pRule =
  570.                     (CEventSinkFilterRule*) pFilter->GetNext(pos);
  571.                 if (PassFilterRule(pRule, pEvent))
  572.                 {
  573.                     bRet = TRUE;
  574.                     break;
  575.                 }
  576.             }
  577.         }
  578.     }
  579.     else
  580.     {
  581.         // We don't have a filter, so the event passes
  582.         bRet = TRUE;
  583.     }
  584.     return bRet;
  585. }
  586. BOOL CRendererEventManager::PassFilterRule(CEventSinkFilterRule* pRule,
  587.                                            CRendererEvent*       pEvent)
  588. {
  589.     BOOL bRet = FALSE;
  590.     if (pRule && pEvent)
  591.     {
  592.         // Do we pass all of the properties?
  593.         if (PassFilterRuleString(pRule->GetURL(),       pEvent->GetURL())      &&
  594.             PassFilterRuleString(pRule->GetFragment(),  pEvent->GetFragment()) &&
  595.             PassFilterRuleString(pRule->GetEventName(), pEvent->GetEventName()))
  596.         {
  597.             bRet = TRUE;
  598.         }
  599.     }
  600.     return bRet;
  601. }
  602. BOOL CRendererEventManager::PassFilterRuleString(const char* pszRule,
  603.                                                  const char* pszEvent)
  604. {
  605.     BOOL bRet = FALSE;
  606.     // If the rule string is NULL, that's an automatic pass,
  607.     // because the rule is not making any statement about this
  608.     // particular property.
  609.     // If the rule string is NOT NULL, then the two
  610.     // strings have to match exactly.
  611.     if (!pszRule || (pszEvent && !strcmp(pszRule, pszEvent)))
  612.     {
  613.         bRet = TRUE;
  614.     }
  615.     return bRet;
  616. }
  617. void CRendererEventManager::ClearSinkFilterList(CHXSimpleList* pList)
  618. {
  619.     if (pList)
  620.     {
  621.         LISTPOSITION pos = pList->GetHeadPosition();
  622.         while (pos)
  623.         {
  624.             CEventSinkFilterRule* pRule =
  625.                 (CEventSinkFilterRule*) pList->GetNext(pos);
  626.             HX_DELETE(pRule);
  627.         }
  628.         pList->RemoveAll();
  629.     }
  630. }
  631. CEventSinkFilterRule::CEventSinkFilterRule(IHXValues* pRule)
  632. {
  633.     m_pRule = pRule;
  634.     if (m_pRule)
  635.     {
  636.         m_pRule->AddRef();
  637.     }
  638. }
  639. CEventSinkFilterRule::~CEventSinkFilterRule()
  640. {
  641.     HX_RELEASE(m_pRule);
  642. }
  643. BOOL CEventSinkFilterRule::Same(CEventSinkFilterRule* pRule)
  644. {
  645.     BOOL bRet = FALSE;
  646.     if (pRule)
  647.     {
  648.         if (SameString(GetURL(),       pRule->GetURL())      &&
  649.             SameString(GetFragment(),  pRule->GetFragment()) &&
  650.             SameString(GetEventName(), pRule->GetEventName()))
  651.         {
  652.             bRet = TRUE;
  653.         }
  654.     }
  655.     return bRet;
  656. }
  657. const char* CEventSinkFilterRule::GetURL() const
  658. {
  659.     return GetString(m_pRule, FILTER_RULE_KEY_URL);
  660. }
  661. const char* CEventSinkFilterRule::GetFragment() const
  662. {
  663.     return GetString(m_pRule, FILTER_RULE_KEY_FRAGMENT);
  664. }
  665. const char* CEventSinkFilterRule::GetEventName() const
  666. {
  667.     return GetString(m_pRule, FILTER_RULE_KEY_EVENTNAME);
  668. }
  669. BOOL CEventSinkFilterRule::SameString(const char* pszA,
  670.                                       const char* pszB)
  671. {
  672.     BOOL bRet = FALSE;
  673.     // If both of the strings are NULL, that's TRUE.
  674.     // If both of the strings are NOT NULL and the
  675.     // strings match, then that's TRUE.
  676.     // Anything else is FALSE.
  677.     if ((!pszA && !pszB) ||
  678.         (pszA  &&  pszB && !strcmp(pszA, pszB)))
  679.     {
  680.         bRet = TRUE;
  681.     }
  682.     return bRet;
  683. }
  684. const char* CEventSinkFilterRule::GetString(IHXValues* pValues,
  685.                                             const char* pszName)
  686. {
  687.     const char* pRet = NULL;
  688.     if (pValues && pszName)
  689.     {
  690.         IHXBuffer* pBuf = NULL;
  691.         pValues->GetPropertyCString(pszName, pBuf);
  692.         if (pBuf)
  693.         {
  694.             pRet = (const char*) pBuf->GetBuffer();
  695.         }
  696.         HX_RELEASE(pBuf);
  697.     }
  698.     return pRet;
  699. }
  700. void CRendererEventManager::RendererEventCallback(void* pParam)
  701. {
  702.     CRendererEventManager* pObj = (CRendererEventManager*)pParam;
  703.     if (pObj)
  704.     {
  705.         pObj->Func();
  706.     }
  707. }
  708. CRendererEvent::CRendererEvent(IHXBuffer* pURLStr,
  709.                                IHXBuffer* pFragmentStr,
  710.                                IHXBuffer* pEventNameStr,
  711.                                IHXValues* pOtherValues)
  712. {
  713.     m_pURLStr       = pURLStr;
  714.     m_pFragmentStr  = pFragmentStr;
  715.     m_pEventNameStr = pEventNameStr;
  716.     m_pOtherValues  = pOtherValues;
  717.     if (m_pURLStr)       m_pURLStr->AddRef();
  718.     if (m_pFragmentStr)  m_pFragmentStr->AddRef();
  719.     if (m_pEventNameStr) m_pEventNameStr->AddRef();
  720.     if (m_pOtherValues)  m_pOtherValues->AddRef();
  721. }
  722. CRendererEvent::~CRendererEvent()
  723. {
  724.     HX_RELEASE(m_pURLStr);
  725.     HX_RELEASE(m_pFragmentStr);
  726.     HX_RELEASE(m_pEventNameStr);
  727.     HX_RELEASE(m_pOtherValues);
  728. }
  729. HX_RESULT CRendererEvent::Fire(IHXEventSink* pSink)
  730. {
  731.     HX_RESULT retVal = HXR_FAIL;
  732.     if (pSink)
  733.     {
  734.         retVal = pSink->EventFired(m_pURLStr,
  735.                                    m_pFragmentStr,
  736.                                    m_pEventNameStr,
  737.                                    m_pOtherValues);
  738.     }
  739.     return retVal;
  740. }
  741. const char* CRendererEvent::GetURL() const
  742. {
  743.     const char* pRet = NULL;
  744.     if (m_pURLStr)
  745.     {
  746.         pRet = (const char*) m_pURLStr->GetBuffer();
  747.     }
  748.     return pRet;
  749. }
  750. const char* CRendererEvent::GetFragment() const
  751. {
  752.     const char* pRet = NULL;
  753.     if (m_pFragmentStr)
  754.     {
  755.         pRet = (const char*) m_pFragmentStr->GetBuffer();
  756.     }
  757.     return pRet;
  758. }
  759. const char* CRendererEvent::GetEventName() const
  760. {
  761.     const char* pRet = NULL;
  762.     if (m_pEventNameStr)
  763.     {
  764.         pRet = (const char*) m_pEventNameStr->GetBuffer();
  765.     }
  766.     return pRet;
  767. }
  768. #endif /* #if defined(HELIX_FEATURE_EVENTMANAGER) */