sitemgr.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:50k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. /****************************************************************************
  36.  * 
  37.  *  Basic PN implementation of the IHXSite classes.
  38.  *
  39.  *
  40.  */
  41. #include "hxcom.h"
  42. #include "hxtypes.h"
  43. #include "hxwintyp.h"
  44. #include "hxmap.h"
  45. #include "hxwin.h"
  46. #include "hxengin.h"
  47. #include "chxxtype.h"
  48. #include "hxsite2.h"
  49. #include "ihxpckts.h"
  50. #include "hxslist.h"
  51. #include "sitemgr.h"
  52. #include "siteprxy.h"
  53. #include "hxvctrl.h"
  54. #include "hxvsurf.h"
  55. #ifndef _WINCE
  56. #ifdef _WINDOWS
  57. #ifdef _WIN32
  58. #include <vfw.h>
  59. #else
  60. #include <drawdib.h>
  61. #endif /* _WIN32 */
  62. #endif /* _WINDOWS */
  63. #if defined(_MACINTOSH)
  64. #include "maclibrary.h"
  65. #include "hx_moreprocesses.h"
  66. #endif
  67. #endif
  68. #include "hxstrutl.h"
  69. #include "hxheap.h"
  70. #ifdef _DEBUG
  71. #undef HX_THIS_FILE
  72. static const char HX_THIS_FILE[] = __FILE__;
  73. #endif
  74. #if !defined(HELIX_CONFIG_NOSTATICS)
  75. INT32 CHXSiteManager::zm_nSiteManagerCount = 0;
  76. #else
  77. #include "globals/hxglobals.h"
  78. const INT32 CHXSiteManager::zm_nSiteManagerCount = 0;
  79. #endif
  80. #if defined(_MACINTOSH) || defined(_MAC_UNIX)
  81. CHXSimpleList CHXSiteManager::zm_SiteManagerList;
  82. #endif
  83. #ifdef _MACINTOSH
  84. BOOL  CHXSiteManager::zm_bWindowRemovedFromList = FALSE;
  85. #endif
  86. /************************************************************************
  87.  *  Method:
  88.  *    Destructor
  89.  */
  90. CHXSiteManager::CHXSiteManager()
  91.     : m_lRefCount(0)
  92.     , m_bInUnHookAll(FALSE)
  93.     , m_bNeedFocus(FALSE)
  94. {
  95. #if defined(HELIX_CONFIG_NOSTATICS)
  96.     INT32& zm_nSiteManagerCount =
  97. HXGlobalInt32::Get(&CHXSiteManager::zm_nSiteManagerCount);
  98. #endif
  99.     
  100. #if defined(_MACINTOSH) || defined(_MAC_UNIX)
  101.     zm_SiteManagerList.AddTail(this);
  102.     zm_nSiteManagerCount++;
  103. #endif
  104. };
  105. /************************************************************************
  106.  *  Method:
  107.  *    Destructor
  108.  */
  109. CHXSiteManager::~CHXSiteManager()
  110. {
  111. #if defined(HELIX_CONFIG_NOSTATICS)
  112.     INT32& zm_nSiteManagerCount =
  113. HXGlobalInt32::Get(&CHXSiteManager::zm_nSiteManagerCount);
  114. #endif
  115.     
  116. #if defined(_MACINTOSH) || defined(_MAC_UNIX)
  117.     LISTPOSITION pos = zm_SiteManagerList.Find(this);
  118.     zm_SiteManagerList.RemoveAt(pos);
  119.     
  120.     zm_nSiteManagerCount--;
  121. #endif
  122.     HX_ASSERT(m_MasterListOfSites.IsEmpty());
  123.     HX_ASSERT(m_SitesToSUS.IsEmpty());
  124.     RemoveMapStrToObj(&m_ChannelsToLists);
  125.     RemoveMapStrToObj(&m_PersistentChannelsToLists);
  126.     RemoveMapStrToObj(&m_LSGNamesToLists);
  127.     RemoveMapStrToObj(&m_PersistentLSGNamesToLists);
  128.     CHXMapStringToOb::Iterator ndx = m_EventHookMap.Begin();
  129.     for (; ndx != m_EventHookMap.End(); ++ndx)
  130.     {
  131.         RemoveList((CHXSimpleList*)*ndx);
  132. delete (CHXSimpleList*)*ndx;
  133.     }
  134.     m_EventHookMap.RemoveAll();
  135.     RemoveList(&m_UnnamedEventHookList);
  136.     CleanupPendingValues();
  137. }
  138. HX_RESULT   
  139. CHXSiteManager::ProcessSiteEvent(CHXEventHookElement* pElement, IHXSite* pSite, 
  140.                                  HXxEvent* pEvent, EVENT_TYPE event_type)
  141. {
  142.     HX_RESULT   rc = HXR_OK;
  143.     if (pElement)
  144.     {
  145.         switch (event_type)
  146.         {
  147.         case SITE_EVENT_GENERAL:
  148.     rc = pElement->m_pHook->HandleEvent(pSite, pEvent);
  149.             break;
  150.         case SITE_EVENT_REMOVED:
  151.             rc = pElement->m_pHook->SiteRemoved(pSite);
  152.             break;
  153.         case SITE_EVENT_ADDED:
  154.             rc = pElement->m_pHook->SiteAdded(pSite);
  155.             break;
  156.         default:
  157.             HX_ASSERT(FALSE);
  158.             break;
  159.         }
  160.     }
  161.     return rc;
  162. }
  163. HX_RESULT
  164. CHXSiteManager::HandleSiteEvent(const char* pRegionName, IHXSite* pSite, 
  165.                                 HXxEvent* pEvent, EVENT_TYPE event_type)
  166. {
  167.     HX_RESULT   rc = HXR_OK;
  168.     // first, walk through named hooks
  169.     CHXSimpleList* pList = NULL;
  170.     if (m_EventHookMap.Lookup(pRegionName, (void*&)pList))
  171.     {
  172. CHXSimpleList::Iterator iter = pList->Begin();
  173. for (; iter != pList->End(); ++iter)
  174. {
  175.     CHXEventHookElement* pElement =
  176. (CHXEventHookElement*)(*iter);
  177.             
  178.             rc = ProcessSiteEvent(pElement, pSite, pEvent, event_type);
  179.     if (pEvent && pEvent->handled)
  180.     {
  181. break;
  182.     }
  183. }
  184.     }
  185.     // try the null hooks
  186.     if (pEvent && !pEvent->handled)
  187.     {
  188. CHXSimpleList::Iterator iter = m_UnnamedEventHookList.Begin();
  189. for (; iter != m_UnnamedEventHookList.End(); ++iter)
  190. {
  191.     CHXEventHookElement* pElement =
  192. (CHXEventHookElement*)(*iter);
  193.             rc = ProcessSiteEvent(pElement, pSite, pEvent, event_type);
  194.     if (pEvent && pEvent->handled)
  195.     {
  196. break;
  197.     }
  198. }
  199.     }
  200.     return rc;
  201. }
  202. void 
  203. CHXSiteManager::HookupHelper(CHXMapPtrToPtr* pMap, char* pActualString, BOOL bIsPersistent, 
  204.                              PTR_TYPE ptr_type, HOOK_TYPE hook_type)
  205. {
  206.     if (pMap)
  207.     {
  208.         CHXMapPtrToPtr::Iterator ndx = pMap->Begin();
  209.         for (; ndx != pMap->End(); ++ndx)
  210.         {
  211.     IHXBuffer* ptempValues = (IHXBuffer*)ndx.get_key(); 
  212.             if (HOOKUP_BY_LSGNAMEWITHSTRING == hook_type)
  213.             {
  214.                 HookupByLSGNameWithString((IHXSiteUserSupplier*) *ndx, 
  215.                                           (char*)(ptempValues->GetBuffer()), 
  216.                                           bIsPersistent);
  217.             }
  218.             else if ( !strcasecmp((char*)(ptempValues->GetBuffer()), pActualString ) ) 
  219.     {
  220.                 switch (hook_type)
  221.                 {
  222.                 case HOOKUP_BY_PLAYTOFROMWITHSTRING:
  223.                     HookupByPlayToFromWithString((IHXSiteUserSupplier*) *ndx,
  224.                                                  (char*)(ptempValues->GetBuffer()), 
  225.                                                  bIsPersistent);
  226.                     break;
  227.                 case HOOKUP_SINGLESITE_BY_LSGNAMEWITHSTRING:
  228.     HookupSingleSiteByLSGNameWithString((IHXSiteUser*) *ndx, 
  229.                                                         (char*)(ptempValues->GetBuffer()), 
  230.                                                         bIsPersistent);
  231.                     break;
  232.                 case HOOKUP_SINGLESITE_BY_PLAYTOFROMWITHSTRING:
  233.                     HookupSingleSiteByPlayToFromWithString((IHXSiteUser*) *ndx,
  234.                                                            (char*)(ptempValues->GetBuffer()), 
  235.                                                            bIsPersistent);
  236.                     break;
  237.                 default:
  238.                     HX_ASSERT(FALSE);
  239.                     break;
  240.                 }
  241.     }
  242.         }
  243.     }
  244. }
  245. void 
  246. CHXSiteManager::RemoveMapStrToObj(CHXMapStringToOb* pMap)
  247. {
  248.     if (pMap)
  249.     {
  250.         CHXMapStringToOb::Iterator ndx = pMap->Begin();
  251.         for (; ndx != pMap->End(); ++ndx)
  252.         {
  253.     CHXMapPtrToPtr* pNode = (CHXMapPtrToPtr*)(*ndx);
  254.     HX_ASSERT(pNode->IsEmpty());
  255.     delete pNode;
  256.         }
  257.         pMap->RemoveAll();
  258.     }
  259. }
  260. void 
  261. CHXSiteManager::RemoveMapPtrToPtr(CHXMapPtrToPtr* pMap)
  262. {
  263.     if (pMap)
  264.     {
  265.         CHXMapPtrToPtr::Iterator i;
  266.         for(i = pMap->Begin(); i!= pMap->End();++i)
  267.         {
  268.             IHXBuffer* pValue = (IHXBuffer*)i.get_key();
  269.     CHXSiteUserSupplierProxy* pProxy = (CHXSiteUserSupplierProxy*) *i; 
  270.     HX_RELEASE(pValue);
  271.     HX_RELEASE(pProxy);
  272.         }
  273.         pMap->RemoveAll();
  274.     }
  275. }
  276. void 
  277. CHXSiteManager::RemoveList(CHXSimpleList* pList)
  278. {
  279.     if (pList)
  280.     {
  281.         CHXSimpleList::Iterator iter = pList->Begin();
  282.         for (; iter != pList->End(); ++iter)
  283.         {
  284.     CHXEventHookElement* pElement = (CHXEventHookElement*)(*iter);
  285.     delete pElement;
  286.         }
  287.         pList->RemoveAll();
  288.     }
  289. }
  290. void CHXSiteManager::CleanupPendingValues()
  291. {
  292.     RemoveMapPtrToPtr(&m_PendingValueToSULSG);
  293.     RemoveMapPtrToPtr(&m_PendingValueToSUSingleLSG);
  294.     RemoveMapPtrToPtr(&m_PendingValueToSUPlayTo);
  295.     RemoveMapPtrToPtr(&m_PendingValueToSUSinglePlayTo);
  296. }
  297. /************************************************************************
  298.  *  Method:
  299.  *    IUnknown::QueryInterface
  300.  */
  301. STDMETHODIMP 
  302. CHXSiteManager::QueryInterface(REFIID riid, void** ppvObj)
  303. {
  304.     QInterfaceList qiList[] =
  305.         {
  306.             { GET_IIDHANDLE(IID_IHXSiteManager), (IHXSiteManager*)this },
  307.             { GET_IIDHANDLE(IID_IHXEventHookMgr), (IHXEventHookMgr*)this },
  308.             { GET_IIDHANDLE(IID_IHXSiteManager2), (IHXSiteManager2*)this },
  309.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXSiteManager*)this },
  310.         };
  311.     
  312.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  313. }
  314. /************************************************************************
  315.  *  Method:
  316.  *    IUnknown::AddRef
  317.  */
  318. STDMETHODIMP_(ULONG32) 
  319. CHXSiteManager::AddRef()
  320. {
  321.     return InterlockedIncrement(&m_lRefCount);
  322. }
  323. /************************************************************************
  324.  *  Method:
  325.  *    IUnknown::Release
  326.  */
  327. STDMETHODIMP_(ULONG32) 
  328. CHXSiteManager::Release()
  329. {
  330.     if (InterlockedDecrement(&m_lRefCount) > 0)
  331.     {
  332.         return m_lRefCount;
  333.     }
  334.     delete this;
  335.     return 0;
  336. }
  337. /************************************************************************
  338.  *  Method:
  339.  *    IHXSiteManager::AddSiteByStringHelper
  340.  */
  341. STDMETHODIMP 
  342. CHXSiteManager::AddSiteByStringHelper
  343. (
  344.     const char* pString,
  345.     IHXSite* pSite,
  346.     CHXMapStringToOb& ByStringMap
  347. )
  348. {
  349.     HRESULT     hresFinal     = HXR_OK;
  350.     void*     pVoid     = NULL;
  351.     CHXMapPtrToPtr* pSiteCollection = NULL;
  352.     /*
  353.      * The basic data structure is as follows: A map is kept 
  354.      * from names to "lists" of sites. We don't actually use
  355.      * a list because we want to quickly detect if the item is
  356.      * already in the list so we use a map for the sites as well.
  357.      */
  358.     /*
  359.      * Find the list in the name to list map, if there is no
  360.      * list in the map then we need to create a new list object
  361.      * and add it to the map.
  362.      */
  363.     if (!ByStringMap.Lookup(pString,pVoid))
  364.     {
  365. pSiteCollection = new CHXMapPtrToPtr();
  366. ByStringMap.SetAt(pString,pSiteCollection);
  367.     }
  368.     else
  369.     {
  370. pSiteCollection = (CHXMapPtrToPtr*)pVoid;
  371.     }
  372.     /*
  373.      * Now that we have the collection of sites we want to see
  374.      * if this item is already in the collection. If it is, then
  375.      * we barf out an error!
  376.      */
  377.     if (pSiteCollection->Lookup(pSite,pVoid))
  378.     {
  379. hresFinal = HXR_INVALID_PARAMETER;
  380. goto exit;
  381.     }
  382.     /*
  383.      * Now that we know its cool to add this to the collection,
  384.      * we do just that...
  385.      */
  386.     pSiteCollection->SetAt(pSite,pSite);
  387.     /*
  388.      * We also want to keep track of which collection we added
  389.      * the site to so that we can more easily (quickly) delete
  390.      * the site when it is removed. To do this we keep a master
  391.      * map of pSite's to the pSiteList items.
  392.      *
  393.      * NOTE: This site should not already be in the master 
  394.      * list. This debug check is a sanity check since our
  395.      * previous efforts should have returned out as an error
  396.      * in the event that a site was added twice!
  397.      */
  398.     HX_ASSERT(!m_MasterListOfSites.Lookup(pSite,pVoid));
  399.     m_MasterListOfSites[pSite] = pSiteCollection;
  400. exit:
  401.     return hresFinal;
  402. }
  403. /************************************************************************
  404.  *  Method:
  405.  *    IHXSiteManager::AddSite
  406.  */
  407. STDMETHODIMP 
  408. CHXSiteManager::AddSite(IHXSite* pSite)
  409. {
  410.     IHXValues*     pProps = NULL;
  411.     IHXBuffer*     pValue = NULL;
  412.     char*     pActualString = NULL;
  413.     HRESULT     hresTemp;
  414.     HRESULT     hresFinal = HXR_OK;
  415.     BOOL     bIsPersistent = FALSE;
  416.     /*
  417.      * We need to get the IHXValues for the site so we know it
  418.      * its for by LSGName or for by plattofrom use. If this is not
  419.      * available then barf up an error.
  420.      */
  421.     hresTemp = pSite->QueryInterface(IID_IHXValues,(void**)&pProps);
  422.     if (HXR_OK != hresTemp)
  423.     {
  424. hresFinal = hresTemp;
  425. goto exit;
  426.     }
  427.     /*
  428.      * let's see if this is a persistent site...
  429.      */
  430.     hresTemp = pProps->GetPropertyCString("Persistent",pValue);
  431.     if(HXR_OK == hresTemp)
  432.     {
  433. bIsPersistent = TRUE;
  434. HX_RELEASE(pValue);
  435.     }
  436.     /*
  437.      * Now let's determine if it's by LSGName or by playtofrom.
  438.      * If one of these is not available then barf up an error.
  439.      */
  440.     /*
  441.      * If the "LayoutGroup" property exists than this is 
  442.      * a site for layout groups by LSGName.
  443.      */
  444.     hresTemp = pProps->GetPropertyCString("LayoutGroup",pValue);
  445.     if (HXR_OK == hresTemp)
  446.     {
  447. pActualString = (char*)pValue->GetBuffer();
  448. if(bIsPersistent)
  449. {
  450.     hresFinal = AddSiteByStringHelper(pActualString, pSite, m_PersistentLSGNamesToLists);
  451. }
  452. else
  453. {
  454.     hresFinal = AddSiteByStringHelper(pActualString, pSite, m_LSGNamesToLists);
  455. }
  456. goto exit;
  457.     }
  458.     /*
  459.      * If the "channel" property exists than this is 
  460.      * a site for renderers playing to a channel.
  461.      */
  462.     hresTemp = pProps->GetPropertyCString("channel",pValue);
  463.     if (HXR_OK == hresTemp)
  464.     {
  465. pActualString = (char*)pValue->GetBuffer();
  466. if(bIsPersistent)
  467. {
  468.     hresFinal = AddSiteByStringHelper(pActualString, pSite, m_PersistentChannelsToLists);
  469. }
  470. else
  471. {
  472.     hresFinal = AddSiteByStringHelper(pActualString, pSite, m_ChannelsToLists);
  473. }
  474. goto exit;
  475.     }
  476. #if 0 ////// NOT YET SUPPORTED ////////
  477.     /*
  478.      * If the "playfrom" property exists than this is 
  479.      * a site for renderers playing from a source/stream combo.
  480.      * Notice that more properties than just "playfrom" are needed
  481.      * to do the actual hookup so we pass the properties in as well.
  482.      */
  483.     hresTemp = pProps->GetPropertyCString("playfrom",pValue);
  484.     if (HXR_OK == hresTemp)
  485.     {
  486. hresFinal = AddSiteByPlayFrom(pProperties,pSite);
  487. goto exit;
  488.     }
  489. #endif
  490. exit:
  491.     /*
  492.      * Cleanup any temporary objects....
  493.      */
  494.     HX_RELEASE(pProps);
  495.     HX_RELEASE(pValue);
  496.     // hookup any leftover orphan value/sites (pending)...
  497.     // first process the LSG list        
  498.     HookupHelper(&m_PendingValueToSULSG, pActualString, bIsPersistent, 
  499.                  SITE_USER_SUPPLIER, HOOKUP_BY_LSGNAMEWITHSTRING);
  500.     // next process the Single LSG list
  501.     HookupHelper(&m_PendingValueToSUSingleLSG, pActualString, bIsPersistent, 
  502.                  SITE_USER, HOOKUP_SINGLESITE_BY_LSGNAMEWITHSTRING);
  503.     
  504.     // next process play to list
  505.     HookupHelper(&m_PendingValueToSUPlayTo, pActualString, bIsPersistent, 
  506.                  SITE_USER_SUPPLIER, HOOKUP_BY_PLAYTOFROMWITHSTRING);
  507.     // next process the Single LSG list
  508.     HookupHelper(&m_PendingValueToSUSinglePlayTo, pActualString, bIsPersistent, 
  509.                  SITE_USER, HOOKUP_SINGLESITE_BY_PLAYTOFROMWITHSTRING);
  510. #ifdef _WINDOWS
  511.     if (m_bNeedFocus && pSite)
  512.     {
  513. IHXSiteWindowless* pWindowLess = NULL;
  514. IHXSiteWindowed*   pWindowed = NULL;
  515. pSite->QueryInterface(IID_IHXSiteWindowless, (void**) &pWindowLess);
  516. if (pWindowLess)
  517. {
  518.     pWindowLess->QueryInterface(IID_IHXSiteWindowed, (void**) &pWindowed);
  519. }
  520. if (pWindowed)
  521. {
  522.     HXxWindow* pWindow = pWindowed->GetWindow();
  523.     if (pWindow && pWindow->window)
  524.     {
  525. // same logic exists in pnvideo/win/winsite.cpp: _SetFocus()
  526. HWND hTmp = ::GetForegroundWindow();
  527. if( ::IsChild(hTmp, (HWND)pWindow->window ))
  528. {
  529.     ::SetFocus((HWND)pWindow->window);
  530. }
  531.     }
  532. }
  533. HX_RELEASE(pWindowLess);
  534. HX_RELEASE(pWindowed);
  535.     }
  536. #endif
  537.     return hresFinal;
  538. }
  539. /************************************************************************
  540.  *  Method:`
  541.  *    IHXSiteManager::RemoveSite
  542.  */
  543. STDMETHODIMP 
  544. CHXSiteManager::RemoveSite(IHXSite* pSite)
  545. {
  546.     void*     pVoid     = NULL;
  547.     CHXMapPtrToPtr* pSiteCollection = NULL;
  548.     IHXValues*     pProps     = NULL;
  549.     IHXBuffer*     pValue     = NULL;
  550.     BOOL     bIsPersistent   = FALSE;
  551.     const char*     pChannelName    = NULL;
  552.     /*
  553.      * This site must have been previously added and therefore
  554.      * should be in the master list of sites.
  555.      */
  556.     if (!m_MasterListOfSites.Lookup(pSite,pVoid)) 
  557.     {
  558. return HXR_INVALID_PARAMETER;
  559.     }
  560.     /*
  561.      * determine whether the site is persistent, and get the name of
  562.      * the site so it can be removed from the channel list
  563.      */
  564.     if(HXR_OK == pSite->QueryInterface(IID_IHXValues,(void**)&pProps))
  565.     {
  566. if(HXR_OK == pProps->GetPropertyCString("Persistent", pValue))
  567. {
  568.     bIsPersistent = TRUE;
  569.     HX_RELEASE(pValue);
  570. }
  571. HX_RELEASE(pProps);
  572.     }
  573.     /*
  574.      *
  575.      */
  576.     /* If we are unhooking all sites, we do not want to unhook site here */
  577.     if (!m_bInUnHookAll)
  578.     {
  579. UnhookSite(pSite, bIsPersistent);
  580.     }
  581.     /*
  582.      * We need to remove the site from whatever collection of
  583.      * sites it is in. This means we are removing it from the
  584.      * collection of sites for it's LSGName if that is how it
  585.      * was added. Instead of determining the properties supported
  586.      * by the site to determine which collection to remove it from
  587.      * we stored the site collection in our master list. Cool, eh?
  588.      */
  589.     pSiteCollection = (CHXMapPtrToPtr*)pVoid;
  590.     HX_ASSERT(pSiteCollection->Lookup(pSite,pVoid));
  591.     pSiteCollection->RemoveKey(pSite);
  592.     /*
  593.      * Of course we also need to remove it from the master site
  594.      * list as well.
  595.      */
  596.     m_MasterListOfSites.RemoveKey(pSite);
  597.     return HXR_OK;
  598. }
  599. STDMETHODIMP
  600. CHXSiteManager::AddEventHookElement
  601. (
  602.     CHXSimpleList*     pList,
  603.     CHXEventHookElement*    pHookElement
  604. )
  605. {
  606.     // insert element into pList
  607.     // in region/uLayer order (greater uLayer
  608.     // before lesser uLayer)
  609.     HX_RESULT rc = HXR_OK;
  610.     BOOL bInserted = FALSE;
  611.     LISTPOSITION pos = pList->GetHeadPosition();
  612.     while(pos)
  613.     {
  614. CHXEventHookElement* pElement = 
  615.     (CHXEventHookElement*)pList->GetAt(pos);
  616. if(pElement->m_uLayer <= pHookElement->m_uLayer)
  617. {
  618.     pList->InsertBefore(pos, pHookElement);
  619.     bInserted = TRUE;
  620.     break;
  621. }
  622. pList->GetNext(pos);
  623.     }
  624.     if(!bInserted)
  625.     {
  626. pList->AddTail(pHookElement);
  627.     }
  628.     return rc;
  629. }
  630. STDMETHODIMP
  631. CHXSiteManager::RemoveEventHookElement
  632. (
  633.     CHXSimpleList* pList,
  634.     IHXEventHook* pHook,
  635.     UINT16 uLayer
  636. )
  637. {
  638.     HX_RESULT rc = HXR_OK;
  639.     LISTPOSITION pos = pList->GetHeadPosition();
  640.     while(pos)
  641.     {
  642. CHXEventHookElement* pThisElement = 
  643.     (CHXEventHookElement*)pList->GetAt(pos);
  644. if(pHook == pThisElement->m_pHook && 
  645.    uLayer == pThisElement->m_uLayer)
  646. {
  647.     delete pThisElement;
  648.     pList->RemoveAt(pos);
  649.     break;
  650. }
  651. pList->GetNext(pos);
  652.     }
  653.     return rc;
  654. }
  655. /************************************************************************
  656.  *  Method:
  657.  *    IHXEventHookMgr::AddHook
  658.  */
  659. STDMETHODIMP 
  660. CHXSiteManager::AddHook
  661. (
  662.     IHXEventHook*  pHook,
  663.     const char*  pRegionName,
  664.     UINT16  uLayer
  665. )
  666. {
  667.     HX_RESULT rc = HXR_OK;
  668.     CHXEventHookElement* pElement = 
  669. new CHXEventHookElement(pHook, uLayer);
  670.     if(pRegionName && strlen(pRegionName) > 0)
  671.     {
  672. CHXSimpleList* pList = NULL;
  673. if (!m_EventHookMap.Lookup(pRegionName, (void*&)pList))
  674. {
  675.     pList = new CHXSimpleList;
  676.     m_EventHookMap[pRegionName] = pList;
  677. }
  678. rc = AddEventHookElement(pList, pElement);
  679.     }
  680.     else
  681.     {
  682. rc = AddEventHookElement(&m_UnnamedEventHookList, pElement);
  683.     }
  684.     return rc;
  685. }
  686. /************************************************************************
  687.  *  Method:
  688.  *    IHXEventHookMgr::RemoveHook
  689.  */
  690. STDMETHODIMP 
  691. CHXSiteManager::RemoveHook
  692. (
  693.     IHXEventHook*  pHook,
  694.     const char*  pRegionName,
  695.     UINT16  uLayer
  696. )
  697. {
  698.     HX_RESULT rc = HXR_OK;
  699.     if(pRegionName && strlen(pRegionName) > 0)
  700.     {
  701. CHXSimpleList* pList = NULL;
  702. if (m_EventHookMap.Lookup(pRegionName, (void*&)pList))
  703. {
  704.     rc = RemoveEventHookElement(pList, pHook, uLayer);
  705. }
  706.     }
  707.     else
  708.     {
  709. rc = RemoveEventHookElement(&m_UnnamedEventHookList, pHook, uLayer);
  710.     }
  711.     return rc;
  712. }
  713. STDMETHODIMP CHXSiteManager::GetNumberOfSites(REF(UINT32) nNumSites )
  714. {
  715.     nNumSites = m_MasterListOfSites.GetCount();
  716.     return HXR_OK;
  717. }
  718. STDMETHODIMP CHXSiteManager::GetSiteAt(UINT32 nIndex, REF(IHXSite*) pSite)
  719. {
  720.     if (!m_MasterListOfSites.GetCount())
  721.     {
  722.         return HXR_FAIL;
  723.     }
  724.     
  725.     POSITION pos = m_MasterListOfSites.GetStartPosition();
  726.     void*   pValue;
  727.     for (UINT32 i = 0; i<=nIndex; i++)
  728.     {
  729.         m_MasterListOfSites.GetNextAssoc(pos, (void*&)pSite, pValue);
  730.     }
  731.     return HXR_OK;
  732. }
  733. /************************************************************************
  734. * Method:
  735. *     CHXSiteManager::HandleHookedEvent
  736. * Purpose:
  737. *   Pass the event to interested parties
  738. */
  739. HX_RESULT
  740. CHXSiteManager::HandleHookedEvent
  741. (
  742.     const char* pRegionName,
  743.     IHXSite* pSite,
  744.     HXxEvent* pEvent
  745. )
  746. {
  747.     return HandleSiteEvent(pRegionName, pSite, pEvent, SITE_EVENT_GENERAL);
  748. }
  749. /************************************************************************
  750. * Method:
  751. *     CHXSiteManager::HookedSiteAdded
  752. * Purpose:
  753. *   Let hooks know about the added site
  754. */
  755. void
  756. CHXSiteManager::HookedSiteAdded
  757. (
  758.     const char* pRegionName,
  759.     IHXSite* pSite
  760. )
  761. {
  762.     HandleSiteEvent(pRegionName, pSite, NULL, SITE_EVENT_ADDED);
  763. }
  764. /************************************************************************
  765. * Method:
  766. *     CHXSiteManager::HookedSiteRemoved
  767. * Purpose:
  768. *   Let hooks know about the removed site
  769. */
  770. void
  771. CHXSiteManager::HookedSiteRemoved
  772. (
  773.     const char* pRegionName,
  774.     IHXSite* pSite
  775. )
  776. {
  777.     HandleSiteEvent(pRegionName, pSite, NULL, SITE_EVENT_REMOVED);
  778. }
  779. /************************************************************************
  780. * Method:
  781. *     CHXSiteManager::IsSitePresent
  782. * Purpose:
  783. *   
  784. */
  785. BOOL
  786. CHXSiteManager::IsSitePresent
  787. (
  788.     IHXSite*     pSite
  789. )
  790. {
  791.     void*   pVoid = NULL;
  792.     return m_MasterListOfSites.Lookup(pSite,pVoid);
  793. }
  794. void 
  795. CHXSiteManager::NeedFocus(BOOL bNeedFocus)
  796. {
  797.     m_bNeedFocus = bNeedFocus;
  798. }
  799. /************************************************************************
  800.  *  Method:
  801.  *    IHXSiteManager::IsSiteAvailableByStringHelper
  802.  */
  803. BOOL
  804. CHXSiteManager::IsSiteAvailableByStringHelper
  805. (
  806.     const char* pString,
  807.     CHXMapStringToOb& ByStringMap
  808. )
  809. {
  810.     BOOL     bAvailable     = FALSE;
  811.     void*     pVoid     = NULL;
  812.     CHXMapPtrToPtr* pSiteCollection = NULL;
  813.     /*
  814.      * The basic data structure is as follows: A map is kept 
  815.      * from names to "lists" of sites. We don't actually use
  816.      * a list because we want to quickly detect if the item is
  817.      * already in the list so we use a map for the sites as well.
  818.      */
  819.     /*
  820.      * Find the list in the name to list map, if there is no
  821.      * list in the map then we know it is surely not available.
  822.      */
  823.     if (!ByStringMap.Lookup(pString,pVoid))
  824.     {
  825. bAvailable = FALSE;
  826. goto exit;
  827.     }
  828.     pSiteCollection = (CHXMapPtrToPtr*)pVoid;
  829.     /*
  830.      * Now that we have the collection of sites we want to see
  831.      * if there are any items in the collection. The collection
  832.      * may exist with no items in it.
  833.      */
  834.     if (pSiteCollection->IsEmpty())
  835.     {
  836. bAvailable = FALSE;
  837. goto exit;
  838.     }
  839.     /*
  840.      * That's all we need to know, if we get this far then we
  841.      * know there exists at least one site by this string.
  842.      */
  843.     bAvailable = TRUE;
  844. exit:
  845.     return bAvailable;
  846. }
  847. /************************************************************************
  848.  *  Method:
  849.  *    CHXSiteManager::IsSiteAvailableByLSGName
  850.  */
  851. BOOL
  852. CHXSiteManager::IsSiteAvailableByLSGName(IHXValues* pProps, BOOL bIsPersistent)
  853. {
  854.     IHXBuffer*     pValue = NULL;
  855.     char*     pActualString = NULL;
  856.     HRESULT     hresTemp;
  857.     BOOL     bAvailable = FALSE;
  858.     /*
  859.      * The properties passed here are the properties of the
  860.      * site user not the site. When associating by LSG name
  861.      * the site's "LayoutGroup" property must match the site
  862.      * users "name" property. So we get the "name" property
  863.      * from the props and look it in our LSGName list.
  864.      */
  865.     hresTemp = pProps->GetPropertyCString("name",pValue);
  866.     HX_ASSERT(HXR_OK == hresTemp);
  867.     pActualString = (char*)pValue->GetBuffer();
  868.     if(bIsPersistent)
  869.     {
  870. bAvailable = IsSiteAvailableByStringHelper(pActualString,m_PersistentLSGNamesToLists);
  871.     }
  872.     else
  873.     {
  874. bAvailable = IsSiteAvailableByStringHelper(pActualString,m_LSGNamesToLists);
  875.     }
  876.     pValue->Release();
  877.     return bAvailable;
  878. }
  879. /************************************************************************
  880.  *  Method:
  881.  *    CHXSiteManager::IsSiteAvailableByPlayToFrom
  882.  */
  883. BOOL
  884. CHXSiteManager::IsSiteAvailableByPlayToFrom(IHXValues* pProps, BOOL bIsPersistent)
  885. {
  886.     IHXBuffer*     pValue = NULL;
  887.     char*     pActualString = NULL;
  888.     HRESULT     hresTemp;
  889.     BOOL     bAvailable = FALSE;
  890.     /*
  891.      * The properties passed here are the properties of the
  892.      * site user not the site. When associating by PlayToFrom
  893.      * the site's "channel" property must match the site
  894.      * users "playto" property. So we get the "playto" property
  895.      * from the props and look it in our Channel list.
  896.      */
  897.     hresTemp = pProps->GetPropertyCString("playto",pValue);
  898.     HX_ASSERT(HXR_OK == hresTemp);
  899.     pActualString = (char*)pValue->GetBuffer();
  900.     if(bIsPersistent)
  901.     {
  902. bAvailable = IsSiteAvailableByStringHelper(pActualString,m_PersistentChannelsToLists);
  903.     }
  904.     else
  905.     {
  906. bAvailable = IsSiteAvailableByStringHelper(pActualString,m_ChannelsToLists);
  907.     }
  908.     pValue->Release();
  909.     return bAvailable;
  910. }
  911. /************************************************************************
  912.  *  Method:
  913.  *    IHXSiteManager::HookupByStringHelper
  914.  */
  915. BOOL
  916. CHXSiteManager::HookupByStringHelper
  917. (
  918.     const char*     pString,
  919.     CHXMapStringToOb&     ByStringMap,
  920.     IHXSiteUserSupplier*   pSUS,
  921.     BOOL     bIsPersistent
  922. )
  923. {
  924.     void*     pVoid     = NULL;
  925.     CHXMapPtrToPtr* pSiteCollection = NULL;
  926.     CHXMapPtrToPtr::Iterator ndxSite;
  927.     /*
  928.      * The basic data structure is as follows: A map is kept 
  929.      * from names to "lists" of sites. We don't actually use
  930.      * a list because we want to quickly detect if the item is
  931.      * already in the list so we use a map for the sites as well.
  932.      */
  933.     /*
  934.      * Find the list in the name to list map, if there is no
  935.      * list in the map then we know it is surely not available.
  936.      */
  937.     if (!ByStringMap.Lookup(pString,pVoid))
  938.     {
  939. return FALSE;
  940.     }
  941.     /*
  942.      * Now that we have the collection of sites we want to actually
  943.      * hook the site user supplier up to each site in the collection.
  944.      */
  945.     pSiteCollection = (CHXMapPtrToPtr*)pVoid;
  946.     ndxSite = pSiteCollection->Begin();
  947.     for (; ndxSite != pSiteCollection->End(); ++ndxSite)
  948.     {
  949. IHXSite* pSite     = (IHXSite*)(*ndxSite);
  950. IHXSiteUser* pUser = NULL;
  951. // If the site has a user then we should not attempt to attach him
  952. // further, if he has a user it probably means that we have 
  953. // already attached him and we are in Wall of TVs mode.
  954. if (pSite->GetUser(pUser) != HXR_OK || !pUser)
  955. {
  956.     HookupSite2SUS(pSite, pSUS, bIsPersistent);
  957. }
  958. HX_RELEASE(pUser);
  959.     }
  960.     return TRUE;
  961. }
  962. //\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\.
  963. ////\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//.
  964. /************************************************************************
  965.  *  Method:
  966.  *    IHXSiteManager::HookupSite2SUS
  967.  */
  968. BOOL
  969. CHXSiteManager::HookupSite2SUS
  970. (
  971.     IHXSite*     pSite, 
  972.     IHXSiteUserSupplier*   pSUS,
  973.     BOOL     bIsPersistent
  974. )
  975. {
  976.     BOOL     retVal     = TRUE;
  977.     void*     pVoid     = NULL;
  978.     IHXSiteWindowed*     pSiteWindowed   = NULL;
  979.     IHXSiteUser*     pUser     = NULL;
  980.     BOOL     bWindowed     = FALSE;
  981.     BOOL     bNeedsWindowed  = FALSE;
  982.     /*
  983.      * We need to find out if this site user needs windowed
  984.      * sites. The first step is to determine if this is a
  985.      * windowed site.
  986.      */
  987.     bWindowed = (HXR_OK == pSite->QueryInterface(
  988. IID_IHXSiteWindowed,
  989. (void**)&pSiteWindowed));
  990.     HX_RELEASE(pSiteWindowed);
  991.     /*
  992.      * If the site user supplier needs windowed sites and this
  993.      * site is windowed, or if the site user supplier can handle
  994.      * windowless sites, then proceed.
  995.      */
  996.     bNeedsWindowed = pSUS->NeedsWindowedSites();
  997.     if (!bNeedsWindowed || (bNeedsWindowed && bWindowed))
  998.     {
  999. /*
  1000.  * Ask the site user supplier to create a new site user
  1001.  * for this particular site.
  1002.  */
  1003. if (HXR_OK == pSUS->CreateSiteUser(pUser))
  1004. {
  1005.     /*
  1006.      * Now actually hook up the site to the site user!
  1007.      *
  1008.      * NOTE: The IHXSite is responsible for calling the
  1009.      *      IHXSiteUser::AttachSite() method.
  1010.      *
  1011.      * NOTE: If this is a layout site user than it will
  1012.      *      create child site in response to the AttachSite()
  1013.      *      method call.
  1014.      */
  1015.     pSite->AttachUser(pUser);
  1016.     /*
  1017.      * We also record the site's that we have created users for
  1018.      * here so that we can unhook everything the next time the
  1019.      * layout is changed. We record the site user supplier
  1020.      * that created the site user so that we can delete that user
  1021.      * as well. NOTE: we shouldn't have already created this
  1022.      * user!
  1023.      */
  1024.     if(bIsPersistent)
  1025.     {
  1026. HX_ASSERT(!m_PersistentSitesToSUS.Lookup(pSite,pVoid));
  1027. m_PersistentSitesToSUS[pSite] = pSUS;
  1028.     }
  1029.     else
  1030.     {
  1031. HX_ASSERT(!m_SitesToSUS.Lookup(pSite,pVoid));
  1032. m_SitesToSUS[pSite] = pSUS;
  1033.     }
  1034.     pSite->AddRef();
  1035.     pSUS->AddRef();
  1036.     pUser->Release();
  1037. }
  1038. else
  1039. {
  1040.     retVal = FALSE;
  1041. }
  1042.     }
  1043.     else
  1044.     {
  1045. retVal = FALSE;
  1046.     }
  1047.     return retVal;
  1048. }
  1049. /************************************************************************
  1050.  *  Method:
  1051.  *    CHXSiteManager::HookupByLSGNameWithString
  1052.  */
  1053. BOOL 
  1054. CHXSiteManager::HookupByLSGNameWithString
  1055. (
  1056.     IHXSiteUserSupplier*   pSUS, 
  1057.     char*     pActualString,
  1058.     BOOL     bIsPersistent
  1059. )
  1060. {
  1061.     BOOL res = FALSE;
  1062.     if(bIsPersistent)
  1063.     {
  1064. res = HookupByStringHelper(pActualString,m_PersistentLSGNamesToLists,pSUS, bIsPersistent);
  1065. if(!res)
  1066. {
  1067.     // check for existence of string in non-persistent list, then move it if it exists
  1068.     void* pVoid = NULL;
  1069.     if(m_LSGNamesToLists.Lookup(pActualString, pVoid))
  1070.     {
  1071. m_LSGNamesToLists.RemoveKey(pActualString);
  1072. m_PersistentLSGNamesToLists.SetAt(pActualString, pVoid);
  1073. res = HookupByStringHelper(pActualString,m_PersistentLSGNamesToLists,pSUS, bIsPersistent);
  1074.     }
  1075. }
  1076.     }
  1077.     else
  1078.     {
  1079. res = HookupByStringHelper(pActualString,m_LSGNamesToLists,pSUS, bIsPersistent);
  1080.     }
  1081.     return res;
  1082. }
  1083. /************************************************************************
  1084.  *  Method:
  1085.  *    CHXSiteManager::HookupByLSGName
  1086.  */
  1087. BOOL 
  1088. CHXSiteManager::HookupByLSGName
  1089. (
  1090.     IHXSiteUserSupplier*   pSUS, 
  1091.     IHXValues*     pProps,
  1092.     BOOL     bIsPersistent
  1093. )
  1094. {
  1095.     IHXBuffer*     pValue = NULL;
  1096.     char*     pActualString = NULL;
  1097.     HRESULT     hresTemp;
  1098.     /*
  1099.      * This method is responsible for fully hooking up the
  1100.      * site user supplier with any and all sites associate with
  1101.      * it's LSG name. NOTE: The Properties passed in are those
  1102.      * of this site user supplier, so first thing is to map from
  1103.      * the appropriate property to the collection of sites having
  1104.      * that property. This is the same as the process for determining
  1105.      * availability.
  1106.      */
  1107.     hresTemp = pProps->GetPropertyCString("name",pValue);
  1108.     HX_ASSERT(HXR_OK == hresTemp);
  1109.     pActualString = (char*)pValue->GetBuffer();
  1110.     CHXSiteUserSupplierProxy* pProxy = new CHXSiteUserSupplierProxy(this,
  1111. pSUS, pActualString);
  1112.     pProxy->AddRef();
  1113.     BOOL res = HookupByLSGNameWithString(pProxy, pActualString, bIsPersistent);
  1114.     // when it fails, save the pProxy & pValue for pending hookup
  1115.     // which is done later during AddSite()
  1116.     if (!res)
  1117.     {
  1118. m_PendingValueToSULSG.SetAt(pValue, pProxy);
  1119.     }
  1120.     else
  1121.     {
  1122.         pValue->Release();
  1123. pProxy->Release(); // now owned by the hookup list
  1124.     }
  1125.     return res;
  1126. }
  1127. /************************************************************************
  1128.  *  Method:
  1129.  *    CHXSiteManager::HookupByPlayToFromWithSting
  1130.  */
  1131. BOOL
  1132. CHXSiteManager::HookupByPlayToFromWithString
  1133. (
  1134.     IHXSiteUserSupplier*   pSUS, 
  1135.     char*     pActualString,
  1136.     BOOL     bIsPersistent
  1137. )
  1138. {
  1139.     BOOL res = FALSE;
  1140.     if(bIsPersistent)
  1141.     {
  1142. res = HookupByStringHelper(pActualString,m_PersistentChannelsToLists,pSUS,bIsPersistent);
  1143. if(!res)
  1144. {
  1145.     // check for existence of string in non-persistent list, then move it if it exists
  1146.     void* pVoid = NULL;
  1147.     if(m_ChannelsToLists.Lookup(pActualString, pVoid))
  1148.     {
  1149. m_ChannelsToLists.RemoveKey(pActualString);
  1150. m_PersistentChannelsToLists.SetAt(pActualString, pVoid);
  1151. res = HookupByStringHelper(pActualString,m_PersistentChannelsToLists,pSUS,bIsPersistent);
  1152.     }
  1153. }
  1154.     }
  1155.     else
  1156.     {
  1157. res = HookupByStringHelper(pActualString,m_ChannelsToLists,pSUS,bIsPersistent);
  1158.     }
  1159.     return res;
  1160. }
  1161. /************************************************************************
  1162.  *  Method:
  1163.  *    CHXSiteManager::HookupByPlayToFrom
  1164.  */
  1165. BOOL
  1166. CHXSiteManager::HookupByPlayToFrom
  1167. (
  1168.     IHXSiteUserSupplier*   pSUS, 
  1169.     IHXValues*     pProps,
  1170.     BOOL     bIsPersistent
  1171. )
  1172. {
  1173.     IHXBuffer*     pValue = NULL;
  1174.     char*     pActualString = NULL;
  1175.     HRESULT     hresTemp;
  1176.     /*
  1177.      * This method is responsible for fully hooking up the
  1178.      * site user supplier with any and all sites associate with
  1179.      * it's playto/from infor. NOTE: The Properties passed in 
  1180.      * are those of this site user supplier, so first thing is 
  1181.      * to map from the appropriate property to the collection 
  1182.      * of sites having that property. This is the same as the 
  1183.      * process for determining availability.
  1184.      */
  1185.     hresTemp = pProps->GetPropertyCString("playto",pValue);
  1186.     HX_ASSERT(HXR_OK == hresTemp);
  1187.     pActualString = (char*)pValue->GetBuffer();
  1188.     CHXSiteUserSupplierProxy* pProxy = new CHXSiteUserSupplierProxy(this,
  1189. pSUS, pActualString);
  1190.     pProxy->AddRef();
  1191.     BOOL res = HookupByPlayToFromWithString(pProxy, pActualString, bIsPersistent);
  1192.     // when it fails, save the pSU & pValue for pending hookup
  1193.     // which is done later during AddSite()
  1194.     if (!res)
  1195.     {
  1196. m_PendingValueToSUPlayTo.SetAt(pValue, pProxy);
  1197.     }
  1198.     else
  1199.     {
  1200.         pValue->Release();
  1201. pProxy->Release(); // now owned by hookup list
  1202.     }
  1203.     return res;
  1204. }
  1205. void
  1206. CHXSiteManager::RemoveSitesByLSGName(IHXValues* pProps, BOOL bIsPersistent)
  1207. {
  1208.     IHXBuffer* pValue = 0;
  1209.     HX_RESULT rc = pProps->GetPropertyCString("name", pValue);
  1210.     if(HXR_OK == rc)
  1211.     {
  1212. const char* pActualString = (const char*)pValue->GetBuffer();
  1213. if(bIsPersistent)
  1214. {
  1215.     void* pVoid;
  1216.     if(m_PersistentLSGNamesToLists.Lookup(pActualString, pVoid))
  1217.     {
  1218. /*
  1219.  * Now that we have the collection of sites we want to actually
  1220.  * hook the site user supplier up to each site in the collection.
  1221.  */
  1222. CHXMapPtrToPtr* pSiteCollection = (CHXMapPtrToPtr*)pVoid;
  1223. CHXMapPtrToPtr::Iterator ndxSite = pSiteCollection->Begin();
  1224. for (; ndxSite != pSiteCollection->End(); ++ndxSite)
  1225. {
  1226.     IHXSite* pSite = (IHXSite*)(*ndxSite);
  1227.     RemoveSite(pSite);
  1228. }
  1229. delete pSiteCollection;
  1230. m_PersistentLSGNamesToLists.RemoveKey(pActualString);
  1231.     }
  1232. }
  1233. pValue->Release();
  1234.     }
  1235. }
  1236. /************************************************************************
  1237.  *  Method:
  1238.  *    CHXSiteManager::UnhookSite
  1239.  */
  1240. void 
  1241. CHXSiteManager::UnhookSite(IHXSite* pSite, BOOL bIsPersistent)
  1242. {
  1243.     HX_ASSERT(pSite);
  1244.     /*
  1245.      * To unhook all the items we simple run through the site users
  1246.      * we created, ask them for their site, tell the site to detach
  1247.      * from the user, and tell the site user supplier to destroy the
  1248.      * site user. That's simple enough...
  1249.      */
  1250.     IHXSiteUserSupplier* pSUS  = 0;
  1251.     IHXSiteUser* pUser = 0;
  1252.     /* Check in both */
  1253.     if(m_PersistentSitesToSUS.Lookup(pSite, (void*&)pSUS))
  1254.     {
  1255. m_PersistentSitesToSUS.RemoveKey(pSite);
  1256. pSite->GetUser(pUser);
  1257. pSite->DetachUser();
  1258. if(pUser && pSUS)
  1259. {
  1260.     pSUS->DestroySiteUser(pUser);
  1261.     pSUS->Release();
  1262. }
  1263. HX_RELEASE(pUser);
  1264. HX_RELEASE(pSite);
  1265.     }
  1266.     else if(m_SitesToSUS.Lookup(pSite, (void*&)pSUS))
  1267.     {
  1268. m_SitesToSUS.RemoveKey(pSite);
  1269. pSite->GetUser(pUser);
  1270. pSite->DetachUser();
  1271. if(pUser && pSUS)
  1272. {
  1273.     pSUS->DestroySiteUser(pUser);
  1274.     pSUS->Release();
  1275. }
  1276. HX_RELEASE(pUser);
  1277. HX_RELEASE(pSite);
  1278.     }
  1279. }
  1280. /************************************************************************
  1281.  *  Method:
  1282.  *    CHXSiteManager::UnhookAll
  1283.  */
  1284. void 
  1285. CHXSiteManager::UnhookAll()
  1286. {
  1287.      m_bInUnHookAll = TRUE;
  1288.     /*
  1289.      * To unhook all the items we simple run through the site users
  1290.      * we created, ask them for their site, tell the site to detach
  1291.      * from the user, and tell the site user supplier to destroy the
  1292.      * site user. That's simple enough...
  1293.      */
  1294.     CHXMapPtrToPtr::Iterator ndxSite = m_SitesToSUS.Begin();
  1295.     for (;  ndxSite != m_SitesToSUS.End(); ++ndxSite)
  1296.     {
  1297. IHXSite* pSite = (IHXSite*)ndxSite.get_key();
  1298. IHXSiteUserSupplier* pSUS  = (IHXSiteUserSupplier*)(*ndxSite);
  1299. IHXSiteUser* pUser = NULL;
  1300. pSite->GetUser(pUser);
  1301. /*
  1302.  * Now actually unhook the site to the site user!
  1303.  *
  1304.  * NOTE: The IHXSite is responsible for calling the
  1305.  *      IHXSiteUser::DetachSite() method.
  1306.  *
  1307.  * NOTE: If this is a layout site user than it will
  1308.  *      destroy the child sites in responses to the
  1309.  *      DetachSite() method call.
  1310.  */
  1311. pSite->DetachUser();
  1312. if (pSUS)
  1313. {
  1314.     if (pUser)
  1315.     {
  1316. pSUS->DestroySiteUser(pUser);
  1317.     }
  1318.     pSUS->Release();
  1319. }
  1320. HX_RELEASE(pUser);
  1321. HX_RELEASE(pSite);
  1322.     }
  1323.     m_SitesToSUS.RemoveAll();
  1324.     CleanupPendingValues();
  1325.     m_bInUnHookAll = FALSE;
  1326. }
  1327. /************************************************************************
  1328.  *  Method:
  1329.  *    CHXSiteManager::HookupSingleSiteByLSGNameWithString
  1330.  */
  1331. BOOL 
  1332. CHXSiteManager::HookupSingleSiteByLSGNameWithString
  1333. (
  1334.     IHXSiteUser*     pSU,
  1335.     char*     pActualString,
  1336.     BOOL     bIsPersistent
  1337. )
  1338. {
  1339.     BOOL res = FALSE;
  1340.     
  1341.     if(bIsPersistent)
  1342.     {
  1343. res = HookupSingleSiteByStringHelper(pActualString,m_PersistentLSGNamesToLists,pSU,bIsPersistent);
  1344. if(!res)
  1345. {
  1346.     // check for existence of string in non-persistent list, then move it if it exists
  1347.     void* pVoid = NULL;
  1348.     if(m_LSGNamesToLists.Lookup(pActualString, pVoid))
  1349.     {
  1350. m_LSGNamesToLists.RemoveKey(pActualString);
  1351. m_PersistentLSGNamesToLists.SetAt(pActualString, pVoid);
  1352. res = HookupSingleSiteByStringHelper(pActualString,m_PersistentLSGNamesToLists,
  1353.     pSU,bIsPersistent);
  1354.     }
  1355. }
  1356.     }
  1357.     else
  1358.     {
  1359. res = HookupSingleSiteByStringHelper(pActualString,m_LSGNamesToLists,pSU,bIsPersistent);
  1360.     }
  1361.     return res;
  1362. }
  1363. /************************************************************************
  1364.  *  Method:
  1365.  *    CHXSiteManager::HookupSingleSiteByLSGName
  1366.  */
  1367. BOOL 
  1368. CHXSiteManager::HookupSingleSiteByLSGName
  1369. (
  1370.     IHXSiteUser*     pSU,
  1371.     IHXValues*     pProps,
  1372.     BOOL     bIsPersistent
  1373. )
  1374. {
  1375.     IHXBuffer*     pValue = NULL;
  1376.     char*     pActualString = NULL;
  1377.     HRESULT     hresTemp;
  1378.     /*
  1379.      * This method is responsible for fully hooking up the
  1380.      * site user supplier with any and all sites associate with
  1381.      * it's LSG name. NOTE: The Properties passed in are those
  1382.      * of this site user supplier, so first thing is to map from
  1383.      * the appropriate property to the collection of sites having
  1384.      * that property. This is the same as the process for determining
  1385.      * availability.
  1386.      */
  1387.     hresTemp = pProps->GetPropertyCString("name",pValue);
  1388.     HX_ASSERT(HXR_OK == hresTemp);
  1389.     pActualString = (char*)pValue->GetBuffer();
  1390.     CHXSiteUserProxy* pProxy = new CHXSiteUserProxy(this,
  1391. pSU, pActualString);
  1392.     pProxy->AddRef();
  1393.     BOOL res = HookupSingleSiteByLSGNameWithString(pProxy, pActualString, bIsPersistent);
  1394.     // when it fails, save the pProxy & pValue for pending hookup
  1395.     // which is done later during AddSite()
  1396.     if (!res)
  1397.     {
  1398. m_PendingValueToSUSingleLSG.SetAt(pValue, pProxy);
  1399.     }
  1400.     else
  1401.     {
  1402.         pValue->Release();
  1403. pProxy->Release(); // now owned by hookup list
  1404.     }
  1405.     return res;
  1406. }
  1407. /************************************************************************
  1408.  *  Method:
  1409.  *    CHXSiteManager::HookupSingleSiteByPlayToFromWithString
  1410.  */
  1411. BOOL
  1412. CHXSiteManager::HookupSingleSiteByPlayToFromWithString
  1413. (
  1414.     IHXSiteUser*     pSU,
  1415.     char*     pActualString,
  1416.     BOOL     bIsPersistent
  1417. )
  1418. {
  1419.     BOOL res = FALSE;
  1420.     if(bIsPersistent)
  1421.     {
  1422. res = HookupSingleSiteByStringHelper(pActualString,m_PersistentChannelsToLists,pSU,bIsPersistent);
  1423. if(!res)
  1424. {
  1425.     // check for existence of string in non-persistent list, then move it if it exists
  1426.     void* pVoid = NULL;
  1427.     if(m_ChannelsToLists.Lookup(pActualString, pVoid))
  1428.     {
  1429. m_ChannelsToLists.RemoveKey(pActualString);
  1430. m_PersistentChannelsToLists.SetAt(pActualString, pVoid);
  1431. res = HookupSingleSiteByStringHelper(pActualString,m_PersistentChannelsToLists,
  1432.     pSU,bIsPersistent);
  1433.     }
  1434. }
  1435.     }
  1436.     else
  1437.     {
  1438. res = HookupSingleSiteByStringHelper(pActualString,m_ChannelsToLists,pSU,bIsPersistent);
  1439.     }
  1440.     return res;
  1441. }
  1442. //////////////////////
  1443. // JEB: Add ret value 
  1444. /************************************************************************
  1445.  *  Method:
  1446.  *    CHXSiteManager::HookupSingleSiteByPlayToFrom
  1447.  */
  1448. BOOL
  1449. CHXSiteManager::HookupSingleSiteByPlayToFrom
  1450. (
  1451.     IHXSiteUser*     pSU,
  1452.     IHXValues*     pProps,
  1453.     BOOL     bIsPersistent
  1454. )
  1455. {
  1456.     IHXBuffer*     pValue = NULL;
  1457.     char*     pActualString = NULL;
  1458.     HRESULT     hresTemp;
  1459.     /*
  1460.      * The properties passed here are the properties of the
  1461.      * site user not the site. When associating by PlayToFrom
  1462.      * the site's "channel" property must match the site
  1463.      * users "playto" property. So we get the "playto" property
  1464.      * from the props and look it in our Channel list.
  1465.      */
  1466.     hresTemp = pProps->GetPropertyCString("playto",pValue);
  1467.     HX_ASSERT(HXR_OK == hresTemp);
  1468.     pActualString = (char*)pValue->GetBuffer();
  1469.     CHXSiteUserProxy* pProxy = new CHXSiteUserProxy(this,
  1470. pSU, pActualString);
  1471.     pProxy->AddRef();
  1472.     BOOL res = HookupSingleSiteByPlayToFromWithString(pProxy, pActualString, bIsPersistent);
  1473.     // when it fails, save the pProxy & pValue for pending hookup
  1474.     // which is done later during AddSite()
  1475.     if (!res)
  1476.     {
  1477. m_PendingValueToSUSinglePlayTo.SetAt(pValue, pProxy);
  1478.     }
  1479.     else
  1480.     {
  1481. pProxy->Release(); // now owned by hookup list
  1482.         pValue->Release();
  1483.     }
  1484.     return res;
  1485. }
  1486. /************************************************************************
  1487.  *  Method:
  1488.  *    IHXSiteManager::HookupSingleSiteByStringHelper
  1489.  */
  1490. BOOL
  1491. CHXSiteManager::HookupSingleSiteByStringHelper
  1492. (
  1493.     const char*     pString,
  1494.     CHXMapStringToOb&     ByStringMap,
  1495.     IHXSiteUser*     pSU,
  1496.     BOOL     bIsPersistent
  1497. )
  1498. {
  1499.     void* pVoid = NULL;
  1500.     CHXMapPtrToPtr* pSiteCollection = NULL;
  1501.     CHXMapPtrToPtr::Iterator ndxSite;
  1502.     IHXSite* pSite = NULL;
  1503.     IHXSiteWindowed* pSiteWindowed = NULL;
  1504.     IHXSiteUser* pUser = pSU;
  1505.     BOOL bWindowed = FALSE;
  1506.     BOOL bNeedsWindowed = FALSE;
  1507.     /*
  1508.      * The basic data structure is as follows: A map is kept 
  1509.      * from names to "lists" of sites. We don't actually use
  1510.      * a list because we want to quickly detect if the item is
  1511.      * already in the list so we use a map for the sites as well.
  1512.      */
  1513.     /*
  1514.      * Find the list in the name to list map, if there is no
  1515.      * list in the map then we know it is surely not available.
  1516.      */
  1517.     if (!ByStringMap.Lookup(pString,pVoid))
  1518.     {
  1519. /* We may get back site from the site supplier at a later time due to 
  1520.  * asynchronous nature. Make this request pending and we will try 
  1521.  * to HookupSingleSiteByStringHelper from within AddSite()
  1522.  */
  1523. return FALSE;
  1524.     }
  1525.     /*
  1526.      * Now that we have the collection of sites we want to actually
  1527.      * hook the site user supplier up to _THE_FIRST_ site in the collection.
  1528.      */
  1529.     pSiteCollection = (CHXMapPtrToPtr*)pVoid;
  1530.     ndxSite = pSiteCollection->Begin();
  1531.     pSite = (IHXSite*)(*ndxSite);
  1532.     /*
  1533.      * We need to find out if this site user needs windowed
  1534.      * sites. The first step is to determine if this is a
  1535.      * windowed site.
  1536.      */
  1537.     bWindowed = (HXR_OK == pSite->QueryInterface(
  1538. IID_IHXSiteWindowed,
  1539. (void**)&pSiteWindowed));
  1540.     HX_RELEASE(pSiteWindowed);
  1541.     
  1542.     /*
  1543.      * If the site user supplier needs windowed sites and this
  1544.      * site is windowed, or if the site user supplier can handle
  1545.      * windowless sites, then proceed.
  1546.      */
  1547.     bNeedsWindowed = pSU->NeedsWindowedSites();
  1548.     if (!bNeedsWindowed || (bNeedsWindowed && bWindowed))
  1549.     {
  1550. /*
  1551.  * Now actually hook up the site to the site user!
  1552.  *
  1553.  * NOTE: The IHXSite is responsible for calling the
  1554.  *      IHXSiteUser::AttachSite() method.
  1555.  *
  1556.  * NOTE: If this is a layout site user than it will
  1557.  *      create child site in response to the AttachSite()
  1558.  *      method call.
  1559.  */
  1560. pSite->AttachUser(pUser);
  1561. /*
  1562.  * We also record the site's that we have created users for
  1563.  * here so that we can unhook everything the next time the
  1564.  * layout is changed. We record the site user supplier
  1565.  * that created the site user so that we can delete that user
  1566.  * as well. NOTE: we shouldn't have already created this
  1567.  * user!
  1568.  */
  1569. if(bIsPersistent)
  1570. {
  1571.     HX_ASSERT(!m_PersistentSitesToSUS.Lookup(pSite,pVoid));
  1572.     /*
  1573.      * NULL means no Site User supplier was provided.
  1574.      */
  1575.     m_PersistentSitesToSUS[pSite] = NULL;
  1576. }
  1577. else
  1578. {
  1579.     HX_ASSERT(!m_SitesToSUS.Lookup(pSite,pVoid));
  1580.     /*
  1581.      * NULL means no Site User supplier was provided.
  1582.      */
  1583.     m_SitesToSUS[pSite] = NULL;
  1584. }
  1585. pSite->AddRef();
  1586.     }
  1587.     return TRUE;
  1588. }
  1589. /************************************************************************
  1590. * Method:
  1591. *     CHXSiteManager::EventOccurred
  1592. * Purpose:
  1593. *   Pass the event to appropriate sites
  1594. */
  1595. void 
  1596. CHXSiteManager::EventOccurred(HXxEvent* pEvent)
  1597. {
  1598. #if defined(_MACINTOSH) || defined(_MAC_UNIX)
  1599.     
  1600.     // xxxbobclark
  1601.     // first, try iterating through sites the old-fashioned way. If there are
  1602.     // any sites here then they'll be in the zm_SiteWindowedList list. If there
  1603.     // aren't, then try using the new pnvideo way.
  1604.     
  1605.     BOOL bHandledOldEvent = FALSE;
  1606.     
  1607. #if 0    /* XXX BOB PLEASE TAKE A LOOK */
  1608.     //determine which sites should get the event & send it over
  1609.     CHXSimpleList::Iterator ndxSite = CHXSiteWindowed::zm_SiteWindowedList.Begin();
  1610.     for (;  ndxSite != CHXSiteWindowed::zm_SiteWindowedList.End(); ++ndxSite)
  1611.     {
  1612. zm_bWindowRemovedFromList = FALSE;
  1613. CHXSiteWindowed* pSiteWindowed = (CHXSiteWindowed*)(*ndxSite);
  1614. bHandledOldEvent = TRUE;
  1615. pSiteWindowed->AddRef();
  1616. pSiteWindowed->MacEventOccurred(pEvent);
  1617. pSiteWindowed->Release();
  1618. /* If a window was removed from this list, iterate again
  1619.  * from the head. 
  1620.  * This *hack* is to avoid O(n^2) processing of events. 
  1621.  * It is required since a new URL may be opened from 
  1622.  * within MacEventOccured() call resulting in 
  1623.  * releasing one(or more) CHXSiteWindows.
  1624.  * 
  1625.  * Potential Problem: Same event may be given to the same 
  1626.  * window more than once.
  1627.  */
  1628. if (zm_bWindowRemovedFromList)
  1629. {
  1630.     zm_bWindowRemovedFromList = FALSE;
  1631.     ndxSite = CHXSiteWindowed::zm_SiteWindowedList.Begin();
  1632. }
  1633.     }
  1634. #endif
  1635.     if (!bHandledOldEvent)
  1636.     {
  1637. CHXSimpleList::Iterator siteManagerNdx = zm_SiteManagerList.Begin();
  1638. for (; siteManagerNdx != zm_SiteManagerList.End(); ++siteManagerNdx)
  1639. {
  1640.     CHXSiteManager* pSiteManager = (CHXSiteManager*)(*siteManagerNdx);
  1641.     CHXMapPtrToPtr::Iterator ndx = pSiteManager->m_MasterListOfSites.Begin();
  1642.     for (; ndx != pSiteManager->m_MasterListOfSites.End(); ++ndx)
  1643.     {
  1644. IHXSite* pSite = (IHXSite*)ndx.get_key();
  1645. IHXSiteWindowless* pSiteWindowless = NULL;
  1646. if (pSite->QueryInterface(IID_IHXSiteWindowless, (void**)&pSiteWindowless) == HXR_OK)
  1647. {
  1648.     pSiteWindowless->EventOccurred(pEvent);
  1649.     pSiteWindowless->Release();
  1650. }
  1651.     }
  1652. }
  1653.     }
  1654. #endif
  1655. }
  1656. /*
  1657.  * CHXEventHookElement methods
  1658.  */
  1659. CHXEventHookElement::CHXEventHookElement
  1660. (
  1661.     IHXEventHook*  pHook,
  1662.     UINT16     uLayer
  1663. ) : m_pHook(pHook)
  1664.   , m_uLayer(uLayer)
  1665. {
  1666.     HX_ASSERT(m_pHook);
  1667.     m_pHook->AddRef();
  1668. }
  1669. CHXEventHookElement::~CHXEventHookElement()
  1670. {
  1671.     HX_RELEASE(m_pHook);
  1672. }