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

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. #include "hxtypes.h"
  36. #if defined( _WIN32 ) || defined( _WINDOWS )
  37. #include "hlxclib/windows.h"
  38. #if !defined(WIN32_PLATFORM_PSPC)
  39. #include <ddeml.h>
  40. #endif /* !defined(WIN32_PLATFORM_PSPC) */
  41. #endif /* defined( _WIN32 ) || defined( _WINDOWS ) */
  42. #include "hxcom.h"
  43. #include "hxresult.h"
  44. //#include "pnlice.h"
  45. #include "timeval.h"
  46. #include "pq.h"
  47. #include "hxcomm.h"
  48. #include "hxengin.h"
  49. #include "hxslist.h"
  50. #if defined(HELIX_FEATURE_NETINTERFACES)
  51. #include "hxnetif.h"
  52. #endif /* HELIX_FEATURE_NETINTERFACES */
  53. #include "ihxpckts.h"
  54. #include "hxfiles.h"
  55. #include "hxcore.h"
  56. #include "hxprefs.h"
  57. #include "auderrs.h"
  58. #include "hxausvc.h"
  59. #include "hxhyper.h"
  60. #include "hxmon.h"
  61. #include "hxclreg.h"
  62. #include "hxcommn.h"
  63. #include "hxsmbw.h"
  64. #include "hxgroup.h"
  65. #include "hxxrsmg.h"
  66. #include "hxxml.h"
  67. #include "hxpac.h"
  68. #include "threngin.h"
  69. #if defined(_UNIX) || (defined(_MACINTOSH) && defined(_CARBON) && defined(THREADS_SUPPORTED))
  70. //XXXgfw Just temp. See below in EventOccurred....
  71. #include "conn.h"
  72. #include "thrdconn.h"
  73. #if defined(_UNIX)
  74. #include "UnixThreads.h"  //For new unix message loop....
  75. #elif defined(_MACINTOSH) && defined(_CARBON) && defined(THREADS_SUPPORTED)
  76. #include "carbthrd.h"
  77. #endif
  78. #include "hxmsgs.h"  //for the messages.
  79. #endif
  80. #include "hxaudses.h"
  81. #include "hxaudply.h"
  82. #include "hxwinver.h"
  83. #include "hxplay.h"
  84. #include "hxclsnk.h"
  85. #include "chxpckts.h"
  86. #include "hxsched.h"
  87. #include "hxoptsc.h"
  88. #include "hxpref.h"
  89. #include "hxwin.h"
  90. #include "hxcorgui.h"
  91. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  92. #include "hxnetapi.h"
  93. #endif /* HELIX_FEATURE_PLAYBACK_NET */
  94. #include "hxhypnv.h"
  95. #include "thrhypnv.h"
  96. #include "hxerror.h"
  97. //#include "corgui.h"
  98. #include "chxuuid.h"
  99. #include "hxplugn.h"
  100. #include "hxshtdn.h"
  101. #include "chunkres.h"
  102. #include "hxthread.h"
  103. #include "hxresmg.h"
  104. #include "portaddr.h"
  105. #include "clntcore.ver"
  106. #include "rtsputil.h"
  107. #ifdef _WIN32
  108. #include "hxconv.h"
  109. #include "platform/win/hxdllldr.h"
  110. #include "filespecutils.h"
  111. #endif
  112. #include "hxpsink.h"
  113. #include "hxcorcom.h"
  114. #include "hxcleng.h"
  115. #include "statinfo.h"
  116. #include "createbwman.h"
  117. #include "dbcs.h"
  118. #include "hxmarsh.h"
  119. //#include "hxmime.h"
  120. #include "plsnkctl.h"
  121. #include "hxmangle.h"
  122. #if defined(_STATICALLY_LINKED) || !defined(HELIX_FEATURE_PLUGINHANDLER2)
  123. #if defined(HELIX_CONFIG_CONSOLIDATED_CORE)
  124. #include "basehand.h"
  125. #else /* HELIX_CONFIG_CONSOLIDATED_CORE */
  126. #include "hxpluginmanager.h"
  127. #endif /* HELIX_CONFIG_CONSOLIDATED_CORE */
  128. #else
  129. #include "plghand2.h"
  130. #endif /* _STATICALLY_LINKED */
  131. #include "dllpath.h"
  132. #include "readpath.h"
  133. #include "hxdir.h"
  134. #include "hxstrutl.h"
  135. #include "validatr.h"
  136. #if !defined(_WINCE) 
  137. #include "hxlang.h"
  138. #endif
  139. #include "crdcache.h"
  140. #include "hxresmgr.h"
  141. #include "hxxmlprs.h"
  142. #include "ihxcookies.h"
  143. #include "cookhlpr.h"
  144. #include "cookies.h"
  145. #if defined(HELIX_FEATURE_SMARTERNETWORK)
  146. #include "preftran.h"
  147. #endif /* HELIX_FEATURE_SMARTERNETWORK */
  148. #include "medblock.h"
  149. #include "viewsrc.h"
  150. #include "hxovmgr.h"
  151. #ifdef _TEST_REPLACED_AUDIO_DEVICE
  152. #include "hxaudev.h"
  153. #endif /*_TEST_REPLACED_AUDIO_DEVICE*/
  154. //#include "../dcondev/dcon.h"
  155. #if defined (_WIN16)
  156. #include <stdlib.h>
  157. #include <windows.h>
  158. #include <shellapi.h>
  159. #endif
  160. #if (defined (_WINDOWS) || defined (_WIN32) ) && !defined(_WINCE) && defined (HELIX_FEATURE_VIDEO)
  161. #include "platform/win/sdidde.h"
  162. #include <vfw.h>
  163. #include "ddraw.h"
  164. //#include "rncolor.h"
  165. #endif /*defined (_WINDOWS) || defined (_WIN32)*/
  166. #include "hxver.h"
  167. #ifdef _OPENWAVE
  168. #include "timeline.h"
  169. #endif
  170. #ifdef _UNIX
  171. #include "unix_net.h"
  172. #include "timeline.h"
  173. #include "hxslctcb.h"
  174. #endif
  175. #ifdef _MACINTOSH
  176. #include "hx_moreprocesses.h"
  177. #include "hxmm.h"
  178. #endif
  179. #ifdef __TCS__
  180. #include "platform/tm1/tm1_net.h"
  181. #include "sitemgr.h"
  182. #include "timeline.h"
  183. #endif
  184. #ifdef _MAC_UNIX
  185. #include "sitemgr.h"
  186. #include "hxwintyp.h"
  187. #include "filespecutils.h"
  188. #endif
  189. #ifdef _MACINTOSH
  190. #include "timeline.h"
  191. #include "sitemgr.h"
  192. #include "hxwintyp.h"
  193. #ifdef _CARBON
  194. #include "genthrd.h"
  195. #include "filespecutils.h"
  196. #endif
  197. #endif
  198. #include "hxheap.h"
  199. #ifdef _DEBUG
  200. #undef HX_THIS_FILE     
  201. static const char HX_THIS_FILE[] = __FILE__;
  202. #endif
  203. #if defined (_WINDOWS) || defined (_WIN32)
  204. #ifndef _DEBUG
  205. #define _MEDIUM_BLOCK 1
  206. #endif
  207. #if 0
  208. #ifdef _DEBUG
  209. #include "allochok.h"
  210. HXAllocHook g_MemoryHook;
  211. #endif
  212. #endif
  213. #endif
  214. #define DEFAULT_MIN_BANDWIDTH   57600       // 56.6 Kbps
  215. #define DEFAULT_MAX_BANDWIDTH   10485800    // 10Mbps
  216. #ifdef _TEST_REPLACED_AUDIO_DEVICE
  217. CHXAudioDevice* z_ReplacedAudioDevice = NULL;
  218. #endif /*_TEST_REPLACED_AUDIO_DEVICE*/
  219. #if defined(HELIX_FEATURE_SYSTEMREQUIRED)
  220. STDMETHODIMP 
  221. HXSystemRequired::QueryInterface(REFIID riid, void** ppvObj)
  222. {
  223.     QInterfaceList qiList[] =
  224.         {
  225.             { GET_IIDHANDLE(IID_IHXSystemRequired), (IHXSystemRequired*)this },
  226.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXSystemRequired*)this },
  227.         };
  228.     
  229.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  230. }
  231. STDMETHODIMP_(ULONG32) 
  232. HXSystemRequired::AddRef()
  233. {
  234.     return InterlockedIncrement(&m_lRefCount);
  235. }
  236. STDMETHODIMP_(ULONG32) 
  237. HXSystemRequired::Release()
  238. {
  239.     if (InterlockedDecrement(&m_lRefCount) > 0)
  240.     {
  241.     return m_lRefCount;
  242.     }
  243.     if(m_lRefCount == 0)
  244.     {
  245.     delete this;
  246.     }
  247.     return 0;
  248. }
  249. STDMETHODIMP 
  250. HXSystemRequired::HasFeatures(IHXUpgradeCollection* pFeatures)
  251. {
  252.     return HXR_FAIL;
  253. }
  254. #endif /* HELIX_FEATURE_SYSTEMREQUIRED */
  255. HXClientEngine::HXClientEngine() :
  256.     m_lRefCount (0)
  257.     ,m_ulPlayerIndex (0)
  258.     ,m_unRegistryID (0)
  259.     ,m_pRegistry(NULL)
  260.     ,m_pCommonClassFactory (0)
  261.     ,m_pCommonClassFactoryOverride (0)
  262.     ,m_pScheduler (0)
  263.     ,m_pOptimizedScheduler(0)
  264.     ,m_pOrigPreferences(0)
  265.     ,m_pPreferences (0)
  266.     ,m_LastError (0)
  267.     ,m_pAudioSession(NULL)
  268.     ,m_bIsSchedulerStarted(FALSE)
  269.     ,m_pOrigNetworkServices(NULL)
  270.     ,m_pNetworkServices(NULL)
  271. #ifdef _UNIX
  272.     ,m_pAsyncIOSelection(NULL)
  273. #if defined(_SOLARIS) // XXXNH: threaded networking currently buggy on solaris
  274.     ,m_bNetworkThreading(FALSE)
  275. #else
  276.     ,m_bNetworkThreading(TRUE)
  277. #endif
  278. #endif
  279.     ,m_pOrigHyperNavigate(NULL)
  280.     ,m_pHyperNavigate(NULL)
  281.     ,m_pPlugin2Handler(NULL)
  282.     ,m_pPlayerSinkControl(NULL)
  283.     ,m_pResMgr(NULL)
  284.     ,m_pExternalResourceManager(NULL)
  285.     ,m_pCredentialsCache(NULL)
  286.     ,m_bInitialized(FALSE)
  287.     ,m_pCoreComm(NULL)
  288. #if defined(THREADS_SUPPORTED)
  289.     ,m_bUseCoreThread(TRUE)
  290. #else
  291.     ,m_bUseCoreThread(FALSE)
  292. #endif
  293.     ,m_bUseCoreThreadExternallySet(FALSE)    
  294.     ,m_pXMLParser(NULL)
  295.     ,m_pValidator(NULL)
  296.     ,m_pCookies(NULL)
  297.     ,m_pCookiesHelper(NULL)
  298.     ,m_pSingleLoadPlugins(NULL)
  299.     ,m_pAllocator(NULL)
  300.     ,m_pViewSource(NULL)
  301.     ,m_pSystemRequired(NULL)
  302.     ,m_pProxyManager(NULL)
  303.     ,m_pPreferredTransportManager(NULL)
  304.     ,m_pOverlayManager(NULL)
  305.     ,m_pMultiPlayPauseSupport(NULL)
  306.     ,m_pASM(NULL)
  307.     ,m_lROBActive(0)
  308.     ,m_pProxyAutoConfig(NULL)
  309.     ,m_pNetInterfaces(NULL)
  310.     ,m_AUName(NULL)
  311. #if defined(_MACINTOSH) && defined(_CARBON) && defined(THREADS_SUPPORTED)
  312.     ,m_bUseMacBlitMutex(FALSE)
  313.     ,m_pMacBlitMutex(NULL)
  314. #endif
  315. {
  316. #ifdef _MEDIUM_BLOCK
  317.     m_pAllocator        = new CMediumBlockAllocator();
  318.     CHXBuffer::SetAllocator(m_pAllocator);
  319. #endif
  320.     m_pCommonClassFactory   = new HXCommonClassFactory((IUnknown*) (IHXClientEngine*)this);
  321.     m_pScheduler        = new HXScheduler((IUnknown*) (IHXClientEngine*)this);
  322. #ifdef HELIX_FEATURE_OPTIMIZED_SCHEDULER
  323.     m_pOptimizedScheduler   = new HXOptimizedScheduler((IUnknown*) (IHXClientEngine*)this);
  324. #endif /* HELIX_FEATURE_OPTIMIZED_SCHEDULER */
  325. #if defined(HELIX_FEATURE_PREFERENCES)
  326. #if defined(HELIX_FEATURE_NO_INTERNAL_PREFS)
  327.     m_pOrigPreferences = NULL;
  328. #elif defined(HELIX_FEATURE_LITEPREFS)
  329.     m_pOrigPreferences      = CHXLitePrefs::CreateObject();
  330. #else
  331.     m_pOrigPreferences      = new HXPreferences;
  332. #endif
  333. #endif /* HELIX_FEATURE_PREFERENCES */
  334. #if defined(HELIX_FEATURE_REGISTRY)
  335.     m_pRegistry         = new HXClientRegistry;
  336. #endif /* HELIX_FEATURE_REGISTRY */
  337. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  338.     m_pOrigNetworkServices  = new HXNetworkServices((IUnknown*) (IHXClientEngine*)this);
  339. #endif /* HELIX_FEATURE_PLAYBACK_NET */
  340. #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
  341. #ifndef _WINCE
  342.     m_pOrigHyperNavigate    = new HXThreadHyperNavigate;
  343. #endif
  344. #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
  345. #if defined(HELIX_FEATURE_ASM)
  346.     m_pASM = CreateBandwidthManager();
  347. #endif /* HELIX_FEATURE_ASM */
  348.     m_pPlayerSinkControl    = new CHXPlayerSinkControl();
  349. #if defined(HELIX_FEATURE_AUTHENTICATION)
  350.     m_pCredentialsCache     = new CHXCredentialsCache();
  351. #endif /* HELIX_FEATURE_AUTHENTICATION */
  352. #if defined(HELIX_FEATURE_XMLPARSER)
  353.     m_pXMLParser        = new HXXMLParser;
  354. #endif /* HELIX_FEATURE_XMLPARSER */
  355. #if defined(HELIX_FEATURE_CORECOMM)
  356.     m_pCoreComm         = HXCoreComm::Create(this);
  357. #endif /* HELIX_FEATURE_CORECOMM */
  358. #if defined(HELIX_FEATURE_SYSTEMREQUIRED)
  359.     m_pSystemRequired       = (IHXSystemRequired*) new HXSystemRequired;
  360. #endif /* HELIX_FEATURE_SYSTEMREQUIRED */
  361. #if defined(HELIX_FEATURE_PROXYMGR)
  362.     m_pProxyManager     = new HXProxyManager();
  363. #endif /* HELIX_FEATURE_PROXYMGR */
  364. #if defined(HELIX_FEATURE_SMARTERNETWORK)
  365.     m_pPreferredTransportManager = new HXPreferredTransportManager((IUnknown*)(IHXClientEngine*)this);
  366. #endif /* HELIX_FEATURE_SMARTERNETWORK */
  367. #if defined(HELIX_FEATURE_OVERLAYMGR)
  368.     m_pOverlayManager       = new HXOverlayManager((IUnknown*)(IHXClientEngine*)this);
  369. #endif /* HELIX_FEATURE_OVERLAYMGR */
  370. #ifdef _MEDIUM_BLOCK
  371.     m_pAllocator->SetScheduler((IUnknown*)m_pScheduler);
  372. #endif
  373. #if defined(_UNIX) || defined(__TCS__)
  374.     m_pSiteEventHandler = NULL;
  375. #endif
  376. #ifdef THREADS_SUPPORTED
  377.     HXMutex::MakeMutex(m_pCoreMutex);
  378. #else
  379. #ifdef _CARBON
  380. #error "Carbon should have threads supported turned on"
  381.     // if running in OS X
  382.     m_pCoreMutex = new HXGenMacMutex;
  383. #else
  384.     HXMutex::MakeStubMutex(m_pCoreMutex);
  385. #endif
  386. #endif
  387.     if (!m_pCommonClassFactory
  388.     || !m_pScheduler
  389. #if defined(HELIX_FEATURE_PREFERENCES) && !defined(HELIX_FEATURE_NO_INTERNAL_PREFS)
  390.     || !m_pOrigPreferences  
  391. #endif /* HELIX_FEATURE_PREFERENCES */
  392. #if defined(HELIX_FEATURE_REGISTRY)
  393.     || !m_pRegistry 
  394. #endif /* HELIX_FEATURE_REGISTRY */
  395. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  396.     || !m_pOrigNetworkServices
  397. #endif /* HELIX_FEATURE_PLAYBACK_NET */
  398. #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
  399. #ifndef _WINCE
  400.     || !m_pOrigHyperNavigate
  401. #endif
  402. #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
  403. #if defined(HELIX_FEATURE_ASM)
  404.         || !m_pASM      
  405. #endif /* HELIX_FEATURE_ASM */
  406.     || !m_pPlayerSinkControl
  407. #if defined(HELIX_FEATURE_AUTHENTICATION)
  408.     || !m_pCredentialsCache 
  409. #endif /* HELIX_FEATURE_AUTHENTICATION */
  410. #if defined(HELIX_FEATURE_SYSTEMREQUIRED)
  411.     || !m_pSystemRequired       
  412. #endif /* HELIX_FEATURE_SYSTEMREQUIRED */
  413. #if defined(HELIX_FEATURE_PROXYMGR)
  414.     || !m_pProxyManager 
  415. #endif /* HELIX_FEATURE_PROXYMGR */
  416. #if defined(HELIX_FEATURE_SMARTERNETWORK)
  417.     || !m_pPreferredTransportManager
  418. #endif /* HELIX_FEATURE_SMARTERNETWORK */
  419.     )
  420.     {
  421.     m_LastError = HXR_OUTOFMEMORY;
  422.     }
  423.     if (!m_LastError)
  424.     {
  425. #ifdef _MEDIUM_BLOCK
  426.     m_pAllocator->AddRef();
  427. #endif
  428.     HX_ADDREF(m_pCommonClassFactory);
  429.     HX_ADDREF(m_pScheduler);
  430. #if defined(HELIX_FEATURE_OPTIMIZED_SCHEDULER)
  431.     HX_ADDREF(m_pOptimizedScheduler);
  432. #endif /* HELIX_FEATURE_OPTIMIZED_SCHEDULER */
  433. #if defined(HELIX_FEATURE_PREFERENCES)
  434.     HX_ADDREF(m_pOrigPreferences);
  435. #endif /* HELIX_FEATURE_PREFERENCES */
  436. #if defined(HELIX_FEATURE_REGISTRY)
  437.     HX_ADDREF(m_pRegistry);
  438. #endif /* HELIX_FEATURE_REGISTRY */
  439. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  440.     HX_ADDREF(m_pOrigNetworkServices);
  441. #endif /* HELIX_FEATURE_PLAYBACK_NET */
  442. #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
  443.     HX_ADDREF(m_pOrigHyperNavigate);
  444. #endif /* HELIX_FEATURE_HYPER_NAVIGATE */
  445. #if defined(HELIX_FEATURE_ASM)
  446.     HX_ADDREF(m_pASM);
  447. #endif /* HELIX_FEATURE_ASM */
  448.     HX_ADDREF(m_pPlayerSinkControl);
  449. #if defined(HELIX_FEATURE_AUTHENTICATION)
  450.     HX_ADDREF(m_pCredentialsCache);
  451. #endif /* HELIX_FEATURE_AUTHENTICATION */
  452. #if defined(HELIX_FEATURE_XMLPARSER)
  453.     HX_ADDREF(m_pXMLParser);
  454. #endif /* HELIX_FEATURE_XMLPARSER */
  455. #if defined(HELIX_FEATURE_SYSTEMREQUIRED)
  456.     HX_ADDREF(m_pSystemRequired);
  457. #endif /* HELIX_FEATURE_SYSTEMREQUIRED */
  458. #if defined(HELIX_FEATURE_PROXYMGR)
  459.     HX_ADDREF(m_pProxyManager);
  460. #endif /* HELIX_FEATURE_PROXYMGR */
  461. #if defined(HELIX_FEATURE_SMARTERNETWORK)
  462.     HX_ADDREF(m_pPreferredTransportManager);
  463. #endif /* HELIX_FEATURE_SMARTERNETWORK */
  464. #if defined(HELIX_FEATURE_OVERLAYMGR)
  465.     HX_ADDREF(m_pOverlayManager);
  466. #endif /* HELIX_FEATURE_OVERLAYMGR */
  467. #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
  468. #ifndef _WINCE
  469.     m_pOrigHyperNavigate->QueryInterface(IID_IHXHyperNavigate, 
  470.                          (void**) &m_pHyperNavigate);
  471. #endif
  472. #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
  473. #if defined(HELIX_FEATURE_PREFERENCES)
  474.     if (m_pOrigPreferences)
  475.     {
  476. m_pOrigPreferences->QueryInterface(IID_IHXPreferences, 
  477.    (void**) &m_pPreferences);
  478.     }
  479. #endif /* HELIX_FEATURE_PREFERENCES */
  480. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  481.     m_pOrigNetworkServices->QueryInterface(IID_IHXNetworkServices, 
  482.                          (void**) &m_pNetworkServices);
  483. #endif /* HELIX_FEATURE_PLAYBACK_NET */
  484.     }
  485.     if (!m_LastError)
  486.     {
  487.     // Assemble registry's key for the preferences 
  488.     char* pCompanyName = new char[strlen(HXVER_COMMUNITY) + 1];
  489.     strcpy(pCompanyName, HXVER_COMMUNITY); /* Flawfinder: ignore */
  490.     char* pProductName = new char[strlen(HXVER_SDK_PRODUCT) + 1];
  491.     strcpy(pProductName, HXVER_SDK_PRODUCT); /* Flawfinder: ignore */
  492.     const ULONG32 nProdMajorVer = TARVER_MAJOR_VERSION;
  493.     const ULONG32 nProdMinorVer = TARVER_MINOR_VERSION;
  494.     char * pComa = HXFindChar(pCompanyName, ',');
  495.     if(pComa)
  496.     {
  497.         *pComa = 0;   
  498.     }
  499.     pComa = HXFindChar(pProductName, ',');
  500.     if(pComa)
  501.     {
  502.         *pComa = 0;   
  503.     }
  504. #if defined(HELIX_FEATURE_PREFERENCES)
  505. #if defined(HELIX_FEATURE_NO_INTERNAL_PREFS)
  506.     HX_RESULT theErr = HXR_OK;
  507. #elif defined(HELIX_FEATURE_LITEPREFS)
  508.     HX_RESULT theErr = m_pOrigPreferences->Open( 
  509.         (const char*) pCompanyName, (const char*) pProductName, nProdMajorVer, nProdMinorVer);
  510.     if( theErr != HXR_OUTOFMEMORY )
  511.     {
  512.        // HXR_FAIL probably just means the prefs file does not exist. We will
  513.        // auto-create it when we do our first write.
  514.        theErr = HXR_OK;
  515.     }
  516. #else
  517.     HX_RESULT theErr = m_pOrigPreferences->OpenUserPref( 
  518.         (const char*) pCompanyName, (const char*) pProductName, nProdMajorVer, nProdMinorVer);
  519. #endif
  520.     if (theErr)
  521.     {
  522.         HX_RELEASE(m_pOrigPreferences);
  523.         HX_RELEASE(m_pPreferences);
  524.     }
  525.     // Read any paths from preferences that weren't set by our loader
  526.     if(HXR_OK == theErr)
  527.     {
  528.         ReadUnsetPathsFromPrefs();
  529.     }
  530. #endif /* HELIX_FEATURE_PREFERENCES */
  531.     HX_VECTOR_DELETE(pCompanyName);
  532.     HX_VECTOR_DELETE(pProductName);
  533. #ifndef _VXWORKS
  534.     // Set the Plugin and Codec directories if they are not yet set
  535.     if (!GetDLLAccessPath()->GetPath(DLLTYPE_PLUGIN))
  536.     {
  537.         CreatePluginDir();
  538.     }
  539.     if (!GetDLLAccessPath()->GetPath(DLLTYPE_CODEC))
  540.     {
  541.         CreateCodecDir();
  542.     }
  543. #endif // _VXWORKS
  544.     }
  545.     if (!m_LastError)
  546.     {
  547. #if defined(_STATICALLY_LINKED) || !defined(HELIX_FEATURE_PLUGINHANDLER2)
  548. #if defined(HELIX_CONFIG_CONSOLIDATED_CORE)
  549.     m_pPlugin2Handler = new BaseHandler();
  550. #else /* HELIX_CONFIG_CONSOLIDATED_CORE */
  551.     m_pPlugin2Handler = new HXPluginManager();
  552. #endif /* HELIX_CONFIG_CONSOLIDATED_CORE */
  553. #else
  554.     m_pPlugin2Handler = new Plugin2Handler();
  555. #endif /* _STATICALLY_LINKED */
  556.     if (m_pPlugin2Handler)
  557.     {
  558.         m_pPlugin2Handler->AddRef();
  559.     }
  560.     else
  561.     {
  562.         m_LastError = HXR_OUTOFMEMORY;
  563.     }
  564.     }
  565. #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
  566. #ifndef _WINCE
  567.     m_pOrigHyperNavigate->Init((IUnknown*) (IHXClientEngine*)this);
  568. #endif
  569. #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
  570. #ifdef _UNIX
  571.     m_select_callbacks = new CHXSimpleList;
  572. #endif
  573. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  574. #ifdef THREADS_SUPPORTED
  575.     /* Start network thread here */
  576.     ThreadEngine::GetThreadEngine();
  577. #endif /*THREADS_SUPPORTED*/
  578. #endif /* HELIX_FEATURE_PLAYBACK_NET */
  579. #if defined(_MACINTOSH) && defined(_CARBON) && defined(THREADS_SUPPORTED) && defined(HELIX_FEATURE_PREFERENCES)
  580.     ReadPrefBOOL(m_pPreferences, "UseMacOptimizedBlitting", m_bUseMacBlitMutex);
  581. #endif
  582. }
  583. HXClientEngine::~HXClientEngine() 
  584. {
  585.     Close();
  586. }
  587. void
  588. HXClientEngine::CreatePrefIfNoExist(const char* pName, const char* pValue)
  589. {
  590. #if defined(HELIX_FEATURE_PREFERENCES)
  591.     IHXBuffer* pBuffer = NULL;
  592.     if (m_pPreferences && m_pPreferences->ReadPref(pName, pBuffer) != HXR_OK)
  593.     {
  594.     pBuffer = new CHXBuffer();
  595.     pBuffer->AddRef();
  596.     
  597.     pBuffer->Set((const unsigned char*)pValue, strlen(pValue) + 1);     
  598.     m_pPreferences->WritePref(pName, pBuffer);
  599.     }
  600.     HX_RELEASE(pBuffer);
  601. #endif
  602. }
  603. void
  604. HXClientEngine::CreatePluginDir()
  605. {
  606. #if !defined(_VXWORKS) && !defined(__TCS__)
  607.     char pPluginDir[_MAX_PATH + 1] = ""; /* Flawfinder: ignore */
  608. #ifdef _WINCE
  609.     SafeStrCpy(pPluginDir, "\", _MAX_PATH + 1);
  610. #elif defined (_WINDOWS) || defined (_WIN32)    
  611.     if (!GetSystemDirectory(pPluginDir, _MAX_PATH))
  612.     {
  613.         SafeStrCpy(pPluginDir, "", _MAX_PATH + 1);
  614.     }
  615.     if (strlen(pPluginDir) > 0 && pPluginDir[strlen(pPluginDir) - 1] != '\')
  616.     {
  617.         SafeStrCat(pPluginDir, "\", _MAX_PATH + 1);
  618.     }
  619.     SafeStrCat(pPluginDir, "Real", _MAX_PATH + 1);
  620. #elif defined (_UNIX)
  621.     SafeStrCpy(pPluginDir, getenv("HOME"), _MAX_PATH+1);
  622.     SafeStrCat(pPluginDir, "/Real", _MAX_PATH+1 - strlen(pPluginDir));
  623. #elif defined (_MACINTOSH)
  624.     // xxxbobclark this assumes that the shared libraries live right
  625.     // next to the executable. It's highly recommended that if you're
  626.     // writing a TLC, you call SetPath yourself...
  627.     SafeStrCpy(pPluginDir, "", _MAX_PATH + 1);
  628. #endif // defined (_WINDOWS) || defined (_WIN32)
  629.     // Set the Path
  630.     GetDLLAccessPath()->SetPath(DLLTYPE_PLUGIN, pPluginDir);
  631. #endif // _VXWORKS
  632. }
  633. void
  634. HXClientEngine::CreateCodecDir()
  635. {
  636. #if !defined(_VXWORKS) && !defined(__TCS__)
  637.     const char* pPath = NULL;
  638.     CHXString codecDir;
  639.     pPath = GetDLLAccessPath()->GetPath(DLLTYPE_PLUGIN);
  640.     if (pPath) codecDir = pPath;
  641.     // xxxbobclark this assumes that the codecs live right next
  642.     // to the executable. It's highly recommended that if you're
  643.     // writing a TLC, you call SetPath yourself...
  644. #ifndef _MACINTOSH
  645.     if (strcmp((const char*)codecDir.Right(1), OS_SEPARATOR_STRING))
  646.     {
  647.     codecDir += OS_SEPARATOR_STRING;
  648.     }
  649.     
  650.     codecDir += "Codecs";
  651. #endif
  652.     // Set the Path
  653.     GetDLLAccessPath()->SetPath(DLLTYPE_CODEC, (const char*)codecDir);
  654. #endif // _VXWORKS
  655. }
  656. void HXClientEngine::_Initialize(void)
  657. {
  658.     IHXBuffer* pValue = NULL;    
  659. #if defined(HELIX_FEATURE_AUDIO)
  660.     if (!m_pAudioSession)
  661.     {
  662.         m_pAudioSession = NewAudioSession();
  663.         if( !m_pAudioSession )
  664.         {
  665.             m_LastError = HXR_OUTOFMEMORY;
  666.             return;
  667.         }
  668.         HX_ADDREF(m_pAudioSession);
  669.     }
  670. #endif /* HELIX_FEATURE_AUDIO */
  671.     // Init IHXRegistry entries
  672.     InitializeRegistry();
  673. #if defined(HELIX_FEATURE_PREFERENCES)
  674.     if (!m_LastError)
  675.     {
  676. #if !defined(HELIX_FEATURE_NO_INTERNAL_PREFS)
  677.     if (m_pOrigPreferences)
  678.     {
  679.         m_pOrigPreferences->SetContext((IUnknown*) (IHXClientEngine*)this);
  680.     }
  681. #endif /* !defined(HELIX_FEATURE_NO_INTERNAL_PREFS) */
  682.     // generate GUID if it doesn't exist
  683.     BOOL bRegenerate = TRUE;
  684.     if (m_pPreferences &&
  685. m_pPreferences->ReadPref(CLIENT_GUID_REGNAME, pValue) == HXR_OK)
  686.     {
  687.         char* pszGUID = DeCipher((char*)pValue->GetBuffer());
  688.         if(pszGUID && strlen(pszGUID) == 36)
  689.         bRegenerate = FALSE;
  690.         HX_RELEASE(pValue);
  691.         if(pszGUID)
  692.         delete[] pszGUID;
  693.     }
  694.     if(bRegenerate)
  695.     {
  696.         CHXString strGUID;
  697.         char* pszGUIDMangled = NULL;
  698.         uuid_tt tmpGUID;
  699.             CHXuuid newGUID;
  700.             newGUID.GetUuid(&tmpGUID);
  701.             if(CHXuuid::HXUuidToString((const uuid_tt*)&tmpGUID, &strGUID) == HXR_OK)
  702.             {
  703.         // mangle the GUID for protection
  704.         pszGUIDMangled = Cipher((char*)strGUID.GetBuffer(strGUID.GetLength()));
  705.         CHXBuffer* lpBuffer = new CHXBuffer();
  706.            
  707.         lpBuffer->AddRef();
  708.         lpBuffer->Set((const unsigned char*)pszGUIDMangled, strlen(pszGUIDMangled)+1);
  709. if (m_pPreferences)
  710. {
  711.     m_pPreferences->WritePref(CLIENT_GUID_REGNAME, lpBuffer);
  712. }
  713.         HX_RELEASE(lpBuffer);
  714.         delete[] pszGUIDMangled;
  715.             }
  716.     }
  717.     // create/initialize the preferences which don't exist  
  718.     CreatePrefIfNoExist("AutoTransport", "1");
  719.     CreatePrefIfNoExist("SendStatistics", "1");
  720.     CreatePrefIfNoExist("AttemptRTSPvMulticast", "1");
  721.     CreatePrefIfNoExist("AttemptRTSPvUDP", "1");
  722.     CreatePrefIfNoExist("AttemptRTSPvTCP", "1");
  723.     CreatePrefIfNoExist("AttemptRTSPvHTTP", "1");
  724.     
  725.     CreatePrefIfNoExist("RTSPProxySupport", "0");
  726.     CreatePrefIfNoExist("RTSPProxyHost", "");
  727.     CreatePrefIfNoExist("RTSPProxyPort", "554");
  728.     CreatePrefIfNoExist("AttemptPNAvMulticast", "1");
  729.     CreatePrefIfNoExist("AttemptPNAvUDP", "1");
  730.     CreatePrefIfNoExist("AttemptPNAvTCP", "1");
  731.     CreatePrefIfNoExist("AttemptPNAvHTTP", "1");
  732.     
  733.     CreatePrefIfNoExist("PNAProxySupport", "0");
  734.     CreatePrefIfNoExist("PNAProxyHost", "");
  735.     CreatePrefIfNoExist("PNAProxyPort", "1090");
  736.     CreatePrefIfNoExist("HTTPProxySupport", "0");
  737.     CreatePrefIfNoExist("HTTPProxyHost", "");
  738.     CreatePrefIfNoExist("HTTPProxyPort", "80");
  739.     InitPaths();
  740.     UINT32 ulMinBandwidth = DEFAULT_MAX_BANDWIDTH;
  741.     /* Add default min/max bandwidth */
  742.     if (m_pPreferences)
  743.     {
  744. m_pPreferences->ReadPref("Bandwidth", pValue);
  745. if (!pValue || (atoi((const char*)pValue->GetBuffer()) == 0))
  746. {
  747.     HX_RELEASE(pValue);
  748.     
  749.     pValue = new CHXBuffer();
  750.     pValue->AddRef();
  751.     
  752.     pValue->SetSize(15);    
  753.     sprintf((char*)pValue->GetBuffer(), "%lu", DEFAULT_MAX_BANDWIDTH); /* Flawfinder: ignore */
  754.     m_pPreferences->WritePref("Bandwidth", pValue);
  755. }
  756. ulMinBandwidth = ::atoi((const char*)pValue->GetBuffer());
  757. HX_RELEASE(pValue);
  758.     }
  759.     UINT32 ulMaxBandwidth = 0;
  760.     ReadPrefINT32(m_pPreferences, "MaxBandwidth", ulMaxBandwidth);
  761.     if (ulMaxBandwidth < ulMinBandwidth)
  762.     {
  763.         /* If we did read some value from the pref but somehow
  764.          * it was set lower to the Bandwidth value, we make
  765.          * it equal to the Bandwidth value...else set it
  766.          * to the default max bandwdith value.
  767.          */
  768.         if (ulMaxBandwidth > 0)
  769.         {
  770.         ulMaxBandwidth = ulMinBandwidth;
  771.         }
  772.         else
  773.         {
  774.         ulMaxBandwidth = DEFAULT_MAX_BANDWIDTH;
  775.         }
  776.         HX_RELEASE(pValue);
  777.         pValue = new CHXBuffer();
  778.         pValue->AddRef();       
  779.         pValue->SetSize(15);    
  780.         if (ulMaxBandwidth < ulMinBandwidth)
  781.         {
  782.         ulMaxBandwidth = ulMinBandwidth;
  783.         }
  784. if (m_pPreferences)
  785. {
  786.     sprintf((char*)pValue->GetBuffer(), "%lu", ulMaxBandwidth); /* Flawfinder: ignore */
  787.     m_pPreferences->WritePref("MaxBandwidth", pValue);
  788. }
  789.     }
  790.     HX_RELEASE(pValue);
  791.     }    
  792. #endif /* HELIX_FEATURE_PREFERENCES */
  793. #if defined(_WIN32) || defined(THREADS_SUPPORTED)
  794.     if (!m_bUseCoreThreadExternallySet)
  795.     {
  796.         ReadPrefBOOL(m_pPreferences, "UseCoreThread", m_bUseCoreThread);  
  797.     }
  798. #endif /*_WIN32*/
  799. #if defined(HELIX_FEATURE_AUDIO)
  800.     if (!m_LastError)
  801.     {
  802.     m_LastError = m_pAudioSession->Init((IUnknown*) (IHXClientEngine*)this);
  803.     m_pAudioSession->SetCoreMutex(m_pCoreMutex);
  804.     }
  805. #endif /* HELIX_FEATURE_AUDIO */
  806. #if defined(HELIX_FEATURE_OPTIMIZED_SCHEDULER)
  807.     if (m_pOptimizedScheduler)
  808.     {
  809. m_pOptimizedScheduler->StartScheduler();
  810.     }
  811. #endif /* HELIX_FEATURE_OPTIMIZED_SCHEDULER */
  812.     InitializeThreadedObjects();
  813.     // load all the plugins 
  814.     if (!m_LastError)
  815.     {
  816. #if defined(HELIX_FEATURE_REGISTRY)
  817.     m_pRegistry->Init((IUnknown*) (IHXClientEngine*)this); 
  818. #endif /* HELIX_FEATURE_REGISTRY */
  819.     // Init the plugin handler. 
  820.     m_pPlugin2Handler->Init((IUnknown*) (IHXClientEngine*)this);   
  821. #if defined(HELIX_FEATURE_PLUGINHANDLER2)
  822.     ULONG32 unTotalPlugins = m_pPlugin2Handler->GetNumOfPlugins2();
  823.     // The basic idea of this for loop is that we want to loop
  824.     // through the list of plugins and load all of the plugins that
  825.     // are non multi-load plugins.
  826.     for (;unTotalPlugins; unTotalPlugins--)
  827.     {
  828.         IHXValues* pPluginProps = NULL;
  829.         ULONG32 isMultiple = 0;
  830.         if (SUCCEEDED(m_pPlugin2Handler->GetPluginInfo((unTotalPlugins-1),
  831.                                                        pPluginProps)) &&
  832.             pPluginProps)
  833.         {
  834.             pPluginProps->GetPropertyULONG32(PLUGIN_LOADMULTIPLE, isMultiple);
  835.             pPluginProps->Release();
  836.         }        
  837.         if(!isMultiple)
  838.         {
  839.         IUnknown* pInstance = NULL;
  840.         m_pPlugin2Handler->GetInstance(unTotalPlugins-1, pInstance);
  841.            
  842.         //If we got an instance of the plugin
  843.         if(pInstance)
  844.         {
  845.             HX_RESULT res;
  846.             IHXPlugin* pFPlugin = 0;
  847.             
  848.             res = pInstance->QueryInterface(IID_IHXPlugin,
  849.                             (void**)&pFPlugin);
  850.             
  851.             //The Plugin should be an IHXPlugin so we should get 
  852.             //an interface.
  853.             if(res == HXR_OK)
  854.             {
  855.               //Finally init the plugin.
  856.               pFPlugin->InitPlugin((IUnknown*) (IHXClientEngine*) this);
  857.               if (!m_pSingleLoadPlugins)
  858.               {
  859.                   m_pSingleLoadPlugins = new CHXSimpleList();
  860.               }
  861.               if (m_pSingleLoadPlugins)
  862.               {
  863.                   //Add this plugin to the Plugin List
  864.                   m_pSingleLoadPlugins->AddTail((void*)pFPlugin);
  865.               }
  866.             } //End of if res==HX_PK statement
  867.             
  868.             //Release
  869.             HX_RELEASE(pInstance);
  870.         
  871.         } //End of if pInstance statement
  872.         } //End of if Plugin is multiload
  873.     }//End of for-loop
  874. #endif /* HELIX_FEATURE_PLUGINHANDLER2 */
  875.     } //End of outer if statement
  876.     // get the resource manager instance
  877. #if defined(HELIX_FEATURE_RESOURCEMGR)
  878.     m_pExternalResourceManager = HXExternalResourceManager::Instance((IUnknown*)(IHXClientEngine*)this);
  879.     m_pResMgr = new CHXResMgr((IUnknown*)(IHXClientEngine*)this);
  880. #endif /* HELIX_FEATURE_RESOURCEMGR */
  881. #if defined(_UNIX) || defined(__TCS__)
  882.     m_pSiteEventHandler = NULL;
  883.     IHXCommonClassFactory* pCCF = NULL;
  884.     if (QueryInterface(IID_IHXCommonClassFactory, (void**) &pCCF) == HXR_OK)
  885.     {
  886.         pCCF->CreateInstance(IID_IHXSiteEventHandler, (void**) &m_pSiteEventHandler);
  887.     }
  888.     HX_RELEASE(pCCF);
  889. #endif
  890. #if defined(HELIX_FEATURE_PROXYMGR)
  891.     m_pProxyManager->Initialize((IUnknown*)(IHXClientEngine*)this);
  892. #endif /* HELIX_FEATURE_PROXYMGR */
  893. #if defined(HELIX_FEATURE_OVERLAYMGR)
  894.     m_pOverlayManager->Initialize();
  895. #endif /* HELIX_FEATURE_OVERLAYMGR */
  896.     if (!m_LastError)
  897.     {
  898.     m_bInitialized = TRUE;
  899.     }
  900. }
  901. /*
  902.  * IUnknown methods
  903.  */
  904. /////////////////////////////////////////////////////////////////////////
  905. //  Method:
  906. //      IUnknown::QueryInterface
  907. //  Purpose:
  908. //      Implement this to export the interfaces supported by your 
  909. //      object.
  910. //
  911. STDMETHODIMP HXClientEngine::QueryInterface(REFIID riid, void** ppvObj)
  912. {
  913.     // might be memory error in constructor...
  914.     if (m_LastError)
  915.     return m_LastError;
  916.     // create the following objects only if needed
  917.     if (!m_pCookiesHelper && IsEqualIID(riid, IID_IHXCookiesHelper))
  918.     {        
  919. #if defined(HELIX_FEATURE_COOKIES)
  920.     m_pCookiesHelper = new HXCookiesHelper();
  921.     if (m_pCookiesHelper)
  922.     {
  923.         m_pCookiesHelper->AddRef();
  924.     }
  925. #endif /* defined(HELIX_FEATURE_COOKIES) */
  926.     }
  927. #if defined(HELIX_FEATURE_META)
  928.     else if (!m_pValidator && IsEqualIID(riid, IID_IHXValidator))
  929.     {
  930.     m_pValidator = new HXValidator((IUnknown*) (IHXClientEngine*)this);
  931.     
  932.     if (m_pValidator)
  933.     {
  934.         m_pValidator->AddRef();
  935.     }
  936.     }
  937. #endif /* HELIX_FEATURE_META */
  938. #if defined(HELIX_FEATURE_VIEWSOURCE)
  939.     else if (!m_pViewSource && IsEqualIID(riid, IID_IHXClientViewSourceSink))
  940.     {
  941.     m_pViewSource = new HXViewSource((IUnknown*) (IHXClientEngine*)this);
  942.     if ( m_pViewSource )
  943.     {
  944.         m_pViewSource->AddRef();
  945.     }
  946.     }
  947. #endif /* HELIX_FEATURE_VIEWSOURCE */
  948. #if defined(HELIX_FEATURE_NETINTERFACES)
  949.     else if (!m_pNetInterfaces && IsEqualIID(riid, IID_IHXNetInterfaces))
  950.     {
  951.     m_pNetInterfaces = new HXNetInterface((IUnknown*)(IHXClientEngine*)this);
  952.     HX_ADDREF(m_pNetInterfaces);
  953.     }
  954. #endif /* HELIX_FEATURE_NETINTERFACES */
  955. #if defined(HELIX_FEATURE_PAC) && defined(HELIX_FEATURE_PLUGINHANDLER2)
  956.     else if (!m_pProxyAutoConfig && IsEqualIID(riid, IID_IHXProxyAutoConfig))
  957.     {
  958.         IUnknown*   pUnknown = NULL;
  959.         if (HXR_OK == m_pPlugin2Handler->FindPluginUsingStrings(PLUGIN_CLASS, 
  960.                                                                 PLUGIN_PAC_TYPE, 
  961.                                                                 NULL,
  962.                                                                 NULL, 
  963.                                                                 NULL, 
  964.                                                                 NULL, 
  965.                                                                 pUnknown))
  966.         {
  967.             pUnknown->QueryInterface(IID_IHXProxyAutoConfig, (void**)&m_pProxyAutoConfig);
  968.             m_pProxyAutoConfig->Init((IUnknown*) (IHXClientEngine*) this);
  969.         }
  970.         HX_RELEASE(pUnknown);
  971.     }
  972. #endif /* HELIX_FEATURE_PAC && HELIX_FEATURE_PLUGINHANDLER2 */
  973. #if defined(_MACINTOSH) && defined(_CARBON) && defined(THREADS_SUPPORTED)
  974.     else if (!m_pMacBlitMutex && IsEqualIID(riid, IID_IHXMacBlitMutex))
  975.     {
  976.     HXMutex::MakeMutex(m_pMacBlitMutex);
  977.     }
  978. #endif
  979. #if defined (HELIX_FEATURE_COOKIES)
  980.     else if (!m_pCookies && (IsEqualIID(riid, IID_IHXCookies) || IsEqualIID(riid, IID_IHXCookies2)))
  981.     {
  982. m_pCookies = NewCookies();
  983. HX_ADDREF(m_pCookies);
  984.     }
  985. #endif /* defined (HELIX_FEATURE_COOKIES) */
  986.     QInterfaceList qiList[] =
  987.         {
  988.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXClientEngine*)this },
  989.             { GET_IIDHANDLE(IID_IHXClientEngine), (IHXClientEngine*)this },
  990.             { GET_IIDHANDLE(IID_IHXClientEngineMapper), (IHXClientEngineMapper*)this },
  991. #if defined(_UNIX) && !defined(_VXWORKS)
  992.             { GET_IIDHANDLE(IID_IHXClientEngineSelector), (IHXClientEngineSelector*)this },
  993. #endif
  994.             { GET_IIDHANDLE(IID_IHXClientEngineSetup), (IHXClientEngineSetup*)this },
  995.             { GET_IIDHANDLE(IID_IHXInterruptState), (IHXInterruptState*)this },
  996.             { GET_IIDHANDLE(IID_IHXShutDownEverything), (IHXShutDownEverything*)this },
  997.             { GET_IIDHANDLE(IID_IHXOverrideDefaultServices), (IHXOverrideDefaultServices*)this },
  998.             { GET_IIDHANDLE(IID_IHXErrorMessages), (IHXErrorMessages*)this },
  999.             { GET_IIDHANDLE(IID_IHXCoreMutex), (IHXCoreMutex*)this }
  1000.         };
  1001.     HX_RESULT retval = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  1002.     if (retval == HXR_OK)
  1003.     {
  1004.         return retval;
  1005.     }
  1006.     
  1007. #if defined _UNIX && !defined _VXWORKS
  1008.     else if (IsEqualIID(riid, IID_IHXAsyncIOSelection))
  1009.     {
  1010.         if (m_pAsyncIOSelection) 
  1011.         {
  1012.         m_pAsyncIOSelection->AddRef();
  1013.             *ppvObj = m_pAsyncIOSelection;  
  1014.         return HXR_OK;
  1015.         }
  1016.     AddRef();
  1017.     *ppvObj = (IHXAsyncIOSelection*)this;
  1018.     return HXR_OK;
  1019.     }
  1020. #endif
  1021. #if defined(_MACINTOSH) && defined(_CARBON) && defined(THREADS_SUPPORTED)
  1022.     else if (IsEqualIID(riid, IID_IHXMacBlitMutex))
  1023.     {
  1024.     AddRef();
  1025.     *ppvObj = (IHXMacBlitMutex*)this;
  1026.     return HXR_OK;
  1027.     }
  1028. #endif
  1029.     // We support Scheduler and Preferences Interface also in the HXClientEngine..
  1030.     else if (m_pCommonClassFactoryOverride &&
  1031.          m_pCommonClassFactoryOverride->
  1032.             QueryInterface(riid, ppvObj) == HXR_OK)
  1033.     {
  1034.     return HXR_OK;
  1035.     }
  1036.     else if (m_pCommonClassFactory &&
  1037.          m_pCommonClassFactory->QueryInterface(riid, ppvObj) == HXR_OK)
  1038.     {
  1039.     return HXR_OK;
  1040.     }
  1041.     else if (m_pScheduler &&
  1042.          m_pScheduler->QueryInterface(riid, ppvObj) == HXR_OK)
  1043.     {
  1044.     return HXR_OK;
  1045.     }
  1046. #ifdef HELIX_FEATURE_OPTIMIZED_SCHEDULER
  1047.     else if (m_pOptimizedScheduler &&
  1048.          m_pOptimizedScheduler->QueryInterface(riid, ppvObj) == HXR_OK)
  1049.     {
  1050.     return HXR_OK;
  1051.     }
  1052. #endif /* HELIX_FEATURE_OPTIMIZED_SCHEDULER */
  1053. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  1054.     else if (m_pNetworkServices &&
  1055.          m_pNetworkServices->QueryInterface(riid, ppvObj) == HXR_OK)
  1056.     {
  1057.     return HXR_OK;
  1058.     }
  1059. #endif /* HELIX_FEATURE_PLAYBACK_NET */
  1060. #if defined(HELIX_FEATURE_REGISTRY)
  1061.     else if (m_pRegistry &&
  1062.          m_pRegistry->QueryInterface(riid, ppvObj) == HXR_OK)
  1063.     {
  1064.     return HXR_OK;
  1065.     }
  1066. #endif /* HELIX_FEATURE_REGISTRY */
  1067. #if defined(HELIX_FEATURE_AUDIO)
  1068.     else if (m_pAudioSession && 
  1069.          m_pAudioSession->QueryInterface(riid,ppvObj) == HXR_OK)
  1070.     {
  1071.     return HXR_OK;
  1072.     }
  1073. #endif /* HELIX_FEATURE_AUDIO */
  1074. #if defined(HELIX_FEATURE_PREFERENCES)
  1075.     else if (m_pPreferences &&
  1076.          m_pPreferences->QueryInterface(riid, ppvObj) == HXR_OK)
  1077.     {
  1078.     return HXR_OK;
  1079.     }
  1080. #endif /* HELIX_FEATURE_AUDIO */
  1081. #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
  1082.     else if (m_pHyperNavigate &&
  1083.          m_pHyperNavigate->QueryInterface(riid, ppvObj) == HXR_OK)
  1084.     {
  1085.     return HXR_OK;
  1086.     }
  1087. #endif /* HELIX_FEATURE_HYPER_NAVIGATE */
  1088.     else if (m_pPlugin2Handler &&
  1089.          m_pPlugin2Handler->QueryInterface(riid, ppvObj) == HXR_OK)
  1090.     {
  1091.     return HXR_OK;
  1092.     }
  1093.     else if (m_pPlayerSinkControl &&
  1094.          m_pPlayerSinkControl->QueryInterface(riid, ppvObj) == HXR_OK)
  1095.     {
  1096.     return HXR_OK;
  1097.     }
  1098. #if defined(HELIX_FEATURE_ASM)
  1099.     else if (m_pASM &&
  1100.          m_pASM->QueryInterface(riid, ppvObj) == HXR_OK)
  1101.     {
  1102.     return HXR_OK;
  1103.     }
  1104. #endif /* HELIX_FEATURE_ASM */
  1105. #if defined(HELIX_FEATURE_META)
  1106.     else if (m_pValidator &&
  1107.          m_pValidator->QueryInterface(riid, ppvObj) == HXR_OK)
  1108.     {
  1109.     return HXR_OK;
  1110.     }
  1111. #endif /* HELIX_FEATURE_META */
  1112. #if defined(HELIX_FEATURE_RESOURCEMGR)
  1113.     else if (m_pExternalResourceManager &&
  1114.          m_pExternalResourceManager->QueryInterface(riid, ppvObj) == HXR_OK)
  1115.     {
  1116.     return HXR_OK;
  1117.     }
  1118. #endif /* HELIX_FEATURE_RESOURCEMGR */
  1119. #if defined(HELIX_FEATURE_AUTHENTICATION)
  1120.     else if (m_pCredentialsCache &&
  1121.          m_pCredentialsCache->QueryInterface(riid, ppvObj) == HXR_OK)
  1122.     {
  1123.     return HXR_OK;
  1124.     }
  1125. #endif /* HELIX_FEATURE_AUTHENTICATION */
  1126. #if defined(HELIX_FEATURE_XMLPARSER)
  1127.     else if (m_pXMLParser &&
  1128.          m_pXMLParser->QueryInterface(riid, ppvObj) == HXR_OK)
  1129.     {
  1130.     return HXR_OK;
  1131.     }
  1132. #endif /* HELIX_FEATURE_XMLPARSER */
  1133. #if defined (HELIX_FEATURE_COOKIES)
  1134.     else if (m_pCookies &&
  1135.          m_pCookies->QueryInterface(riid, ppvObj) == HXR_OK)
  1136.     {
  1137.     return HXR_OK;
  1138.     }
  1139.     else if (m_pCookiesHelper &&
  1140.          m_pCookiesHelper->QueryInterface(riid, ppvObj) == HXR_OK)
  1141.     {
  1142.     return HXR_OK;
  1143.     }
  1144. #endif /* HELIX_FEATURE_COOKIES */
  1145. #if defined(_MEDIUM_BLOCK)
  1146.     else if (m_pAllocator &&
  1147.      m_pAllocator->QueryInterface(riid, ppvObj) == HXR_OK)
  1148.     {
  1149.     return HXR_OK;
  1150.     }
  1151. #endif /* _MEDIUM_BLOCK */
  1152. #if defined(HELIX_FEATURE_VIEWSOURCE)
  1153.     else if (m_pViewSource &&
  1154.     m_pViewSource->QueryInterface(riid, ppvObj) == HXR_OK)
  1155.     {
  1156.     return HXR_OK;
  1157.     }
  1158. #endif /* HELIX_FEATURE_VIEWSOURCE */
  1159. #if defined(HELIX_FEATURE_SYSTEMREQUIRED)
  1160.     else if (m_pSystemRequired && 
  1161.         m_pSystemRequired->QueryInterface(riid, ppvObj) == HXR_OK)
  1162.     {
  1163.     return HXR_OK;
  1164.     }
  1165. #endif /* HELIX_FEATURE_SYSTEMREQUIRED */
  1166. #if defined(HELIX_FEATURE_PROXYMGR)
  1167.     else if (m_pProxyManager &&
  1168.          m_pProxyManager->QueryInterface(riid, ppvObj) == HXR_OK)
  1169.     {
  1170.     return HXR_OK;
  1171.     }    
  1172. #endif /* HELIX_FEATURE_PROXYMGR */
  1173. #if defined(HELIX_FEATURE_SMARTERNETWORK)
  1174.     else if (m_pPreferredTransportManager &&
  1175.          m_pPreferredTransportManager->QueryInterface(riid, ppvObj) == HXR_OK)
  1176.     {
  1177.     return HXR_OK;
  1178.     }
  1179. #endif /* HELIX_FEATURE_SMARTERNETWORK */
  1180. #if defined(HELIX_FEATURE_OVERLAYMGR)
  1181.     else if (m_pOverlayManager &&
  1182.          m_pOverlayManager->QueryInterface(riid, ppvObj) == HXR_OK)
  1183.     {
  1184.     return HXR_OK;
  1185.     }
  1186. #endif /* HELIX_FEATURE_OVERLAYMGR */
  1187.     else if (m_pMultiPlayPauseSupport && IsEqualIID(riid, IID_IHXMultiPlayPauseSupport) &&
  1188.     m_pMultiPlayPauseSupport->QueryInterface(riid, ppvObj) == HXR_OK)
  1189.     {
  1190.     return HXR_OK;
  1191.     }
  1192. #if defined(HELIX_FEATURE_NETINTERFACES)
  1193.     else if (m_pNetInterfaces &&
  1194.          m_pNetInterfaces->QueryInterface(riid, ppvObj) == HXR_OK)
  1195.     {
  1196.     return HXR_OK;
  1197.     }
  1198. #endif /* HELIX_FEATURE_NETINTERFACES */
  1199. #if defined(HELIX_FEATURE_PAC)
  1200.     else if (m_pProxyAutoConfig &&
  1201.          m_pProxyAutoConfig->QueryInterface(riid, ppvObj) == HXR_OK)
  1202.     {
  1203.         return HXR_OK;
  1204.     }
  1205. #endif /* HELIX_FEATURE_PAC */
  1206.     *ppvObj = NULL;
  1207.     return HXR_NOINTERFACE;
  1208. }
  1209. /////////////////////////////////////////////////////////////////////////
  1210. //  Method:
  1211. //      IUnknown::AddRef
  1212. //  Purpose:
  1213. //      Everyone usually implements this the same... feel free to use
  1214. //      this implementation.
  1215. //
  1216. STDMETHODIMP_(ULONG32) HXClientEngine::AddRef()
  1217. {
  1218.     return InterlockedIncrement(&m_lRefCount);
  1219. }
  1220. /////////////////////////////////////////////////////////////////////////
  1221. //  Method:
  1222. //      IUnknown::Release
  1223. //  Purpose:
  1224. //      Everyone usually implements this the same... feel free to use
  1225. //      this implementation.
  1226. //
  1227. STDMETHODIMP_(ULONG32) HXClientEngine::Release()
  1228. {
  1229.     if (InterlockedDecrement(&m_lRefCount) > 0)
  1230.     {
  1231.     return m_lRefCount;
  1232.     }
  1233.     if(m_lRefCount == 0)
  1234.     {
  1235.     delete this;
  1236.     }
  1237.     return 0;
  1238. }
  1239. /*
  1240.  * IHXClientEngine methods
  1241.  */
  1242. /************************************************************************
  1243.  *  Method:
  1244.  *      IHXClientEngine::CreatePlayer
  1245.  *  Purpose:
  1246.  *      TBD.
  1247.  *
  1248.  */
  1249. STDMETHODIMP HXClientEngine::CreatePlayer(IHXPlayer* &pPlayer)
  1250. {
  1251.     if (!m_bInitialized)
  1252.     {
  1253.         _Initialize();
  1254.     }
  1255.     // might be memory error in constructor...
  1256.     if (m_LastError)
  1257.     return m_LastError;
  1258.     HXPlayer*      lpPlayer        = NewPlayer();
  1259.     if( !lpPlayer )
  1260.     {
  1261.         m_LastError = HXR_OUTOFMEMORY;
  1262.         return m_LastError;
  1263.     }
  1264.     CHXAudioPlayer* pAudioPlayer    = 0;
  1265.     HX_RESULT       theErr      = HXR_OK;
  1266.     UINT32      unRegistryID            = 0;
  1267.     char        szPlayerName[MAX_DISPLAY_NAME]  = {0}; /* Flawfinder: ignore */
  1268.     if (!lpPlayer)
  1269.     {
  1270.     return HXR_OUTOFMEMORY;
  1271.     }
  1272.     /* Local AddRef to keep the object around */
  1273.     lpPlayer->AddRef();
  1274.     // create registry entry for this player
  1275.     SafeSprintf(szPlayerName, MAX_DISPLAY_NAME, "Statistics.Player%ld", m_ulPlayerIndex);
  1276.     m_ulPlayerIndex++;
  1277.     
  1278. #if defined(HELIX_FEATURE_REGISTRY)
  1279.     unRegistryID = m_pRegistry->AddComp(szPlayerName);
  1280. #endif /* HELIX_FEATURE_REGISTRY */
  1281. #if defined(HELIX_FEATURE_AUDIO)
  1282.     theErr = m_pAudioSession->CreateAudioPlayer(&pAudioPlayer);
  1283.     
  1284.     if (theErr == HXR_OK)
  1285.     {
  1286.     theErr = lpPlayer->Init(this, unRegistryID, pAudioPlayer);
  1287.     lpPlayer->SetInterrupt(m_bUseCoreThread);
  1288.     /* HXPlayer will keep it around */
  1289.     HX_RELEASE(pAudioPlayer);
  1290.     }
  1291. #endif /* HELIX_FEATURE_AUDIO */
  1292.     if (theErr == HXR_OK)
  1293.     {
  1294.       //Return Copy
  1295.       pPlayer   = lpPlayer;
  1296.       pPlayer->AddRef();
  1297.       // Keep Copy
  1298.       m_PlayerList.AddHead((void *) pPlayer);
  1299.       pPlayer->AddRef();
  1300.       m_pPlayerSinkControl->PlayerCreated(pPlayer);
  1301.     } 
  1302.     //Release Local Copy
  1303.     HX_RELEASE(lpPlayer);
  1304.     return theErr;
  1305. }
  1306. CHXAudioSession*
  1307. HXClientEngine::NewAudioSession()
  1308. {
  1309.     return (new CHXAudioSession());
  1310. }
  1311. HXPlayer*
  1312. HXClientEngine::NewPlayer()
  1313. {
  1314.     return (new HXPlayer());
  1315. }
  1316. HXCookies*
  1317. HXClientEngine::NewCookies()
  1318. {
  1319.     HXCookies* pRet = NULL;
  1320. #if defined(HELIX_FEATURE_COOKIES)
  1321.     pRet = (new HXCookies((IUnknown*) (IHXClientEngine*) this));
  1322. #endif /* defined(HELIX_FEATURE_COOKIES) */
  1323.     return pRet;
  1324. }
  1325. /************************************************************************
  1326.  *  Method:
  1327.  *      IHXClientEngine::ClosePlayer
  1328.  *  Purpose:
  1329.  *      Called by the engine when it is done using the player...
  1330.  *
  1331.  */
  1332. STDMETHODIMP HXClientEngine::ClosePlayer(IHXPlayer*    pPlayer)
  1333. {
  1334.     CHXSimpleList::Iterator lIterator   = m_PlayerList.Begin();
  1335.     LISTPOSITION lPosition = m_PlayerList.Find(pPlayer);
  1336.     if (lPosition)
  1337.     {
  1338.     m_PlayerList.RemoveAt(lPosition);
  1339.     HXPlayer* pHXPlayer = (HXPlayer*) pPlayer;
  1340.     m_pPlayerSinkControl->PlayerClosed(pPlayer);
  1341.     pHXPlayer->ClosePlayer();
  1342.     pPlayer->Release();
  1343.     return HXR_OK;
  1344.     }
  1345.     else
  1346.     {
  1347.     return HXR_INVALID_PARAMETER;
  1348.     }
  1349. }
  1350. /************************************************************************
  1351.  *  Method:
  1352.  *    IHXClientEngine::GetPlayerCount
  1353.  *  Purpose:
  1354.  *    Returns the current number of source instances supported by
  1355.  *    this player instance.
  1356.  */
  1357. STDMETHODIMP_(UINT16) HXClientEngine::GetPlayerCount()
  1358. {
  1359.     return (UINT16)m_PlayerList.GetCount();
  1360. }
  1361. /************************************************************************
  1362.  *  Method:
  1363.  *    IHXClientEngine::GetPlayer
  1364.  *  Purpose:
  1365.  *    Returns the Nth source instance supported by this player.
  1366.  */
  1367. STDMETHODIMP HXClientEngine::GetPlayer
  1368. (
  1369.     UINT16      nIndex,
  1370.     REF(IUnknown*)  pUnknown
  1371. )
  1372. {
  1373.     LISTPOSITION pos = m_PlayerList.FindIndex(nIndex);
  1374.     if (!pos)
  1375.     {
  1376.     pUnknown = NULL;
  1377.     return HXR_INVALID_PARAMETER;
  1378.     }
  1379.     HXPlayer* pPlayer = (HXPlayer*)m_PlayerList.GetAt(pos);
  1380.     HX_ASSERT(pPlayer);
  1381.     return pPlayer->QueryInterface(IID_IUnknown,(void**)&pUnknown);
  1382. }
  1383.  
  1384. /************************************************************************
  1385.  *  Method:
  1386.  *      IHXClientEngine::GetPlayerBySite
  1387.  *  Purpose:
  1388.  *      Returns the IHXPlayer instance supported by this client 
  1389.  *      engine instance that contains the specified IHXSite.
  1390.  */
  1391. STDMETHODIMP HXClientEngine::GetPlayerBySite
  1392. (
  1393.     IHXSite*           pSite,
  1394.     REF(IUnknown*)  pUnknown
  1395. )
  1396. {
  1397.     pUnknown = NULL;
  1398.     HXPlayer* pPlayer = NULL;
  1399.     for (int i = 0; i < m_PlayerList.GetCount(); ++i)
  1400.     {
  1401.         LISTPOSITION pos = m_PlayerList.FindIndex(i);
  1402.         pPlayer = (HXPlayer*)m_PlayerList.GetAt(pos);
  1403.         if (pPlayer->IsSitePresent(pSite))
  1404.             return pPlayer->QueryInterface(IID_IUnknown,(void**)&pUnknown);
  1405.     }
  1406.     return HXR_FAIL;
  1407. }
  1408. /************************************************************************
  1409. *   Method:
  1410. *       IHXClientEngine::EventOccurred
  1411. *   Purpose:
  1412. *       Clients call this to pass OS events to all players. HXxEvent
  1413. *       defines a cross-platform event.
  1414. */
  1415. STDMETHODIMP HXClientEngine::EventOccurred(HXxEvent* pEvent)
  1416. {
  1417. #if defined(_UNIX)
  1418. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  1419. #if defined(_UNIX_THREADED_NETWORK_IO)
  1420.     if( !m_bNetworkThreading )
  1421.         if (!pEvent)
  1422.             unix_TCP::process_idle();
  1423.     //XXXgfw Just keep this for unix gold. Then do it right.
  1424.     //This is the new unix message loop.
  1425.     //Check the main app thread for any messages.
  1426.     if(m_bNetworkThreading)
  1427.     {
  1428.         ThreadEngine* pEngine = ThreadEngine::GetThreadEngine();
  1429.         HX_ASSERT( pEngine );
  1430.         HXUnixThread* pMainAppThread = (HXUnixThread*)pEngine->GetMainAppThread();
  1431.         HX_ASSERT( pMainAppThread );
  1432.         struct HXThreadMessage msg;
  1433.         
  1434.         while(pMainAppThread->PeekMessage(&msg, 0, 0, TRUE )==HXR_OK)
  1435.         {
  1436.             if( msg.m_ulMessage != 0 )
  1437.             {
  1438.                 ThreadedConn* pThat = (ThreadedConn*)msg.m_pParam1;
  1439.                 if (pThat != NULL)
  1440.                 {
  1441.                     switch(msg.m_ulMessage)
  1442.                     {
  1443.                        case HXMSG_ASYNC_DNS:
  1444.                            pThat->OnAsyncDNS((BOOL)msg.m_pParam2);
  1445.                            break;
  1446.                        case HXMSG_ASYNC_CONNECT:
  1447.                            pThat->OnConnect((BOOL)msg.m_pParam2);
  1448.                            break;
  1449.                        case HXMSG_ASYNC_READ:
  1450.                            pThat->OnReadNotification();
  1451.                            break;
  1452.                        case HXMSG_ASYNC_WRITE:
  1453.                            pThat->OnWriteNotification();
  1454.                            break;
  1455.                        case HXMSG_ASYNC_ACCEPT:
  1456.                            pThat->OnAcceptNotification();
  1457.                            break;
  1458.                        default:
  1459.                            HX_ASSERT("Unknown message" == NULL );
  1460.                            break;
  1461.                     }
  1462.                 }
  1463.             }
  1464.         }
  1465.     }
  1466.      
  1467. #else
  1468.     if (!pEvent)
  1469.         unix_TCP::process_idle();
  1470. #endif //_UNIX_THREADED_NETWORK_IO    
  1471. #endif //HELIX_FEATURE_PLAYBACK_NET
  1472.     
  1473. #ifdef _MAC_UNIX
  1474.     if (m_pCoreMutex)
  1475.     {
  1476.         m_pCoreMutex->Lock();
  1477.     }
  1478.     LISTPOSITION lPosition = m_PlayerList.GetHeadPosition();
  1479.     HXPlayer* pPlayer;
  1480.     while (lPosition != NULL)
  1481.     {
  1482.         pPlayer = (HXPlayer*) m_PlayerList.GetNext(lPosition);
  1483.         pPlayer->EventOccurred(pEvent);
  1484.     }
  1485.        
  1486. #ifdef HELIX_FEATURE_VIDEO
  1487.     CHXSiteManager::EventOccurred(pEvent);
  1488. #endif
  1489.     
  1490.     if (m_pCoreMutex)
  1491.     {
  1492.         m_pCoreMutex->Unlock();
  1493.     }
  1494.     /* Do not pump the core on any other event since the top level
  1495.      * sends fake update events with doctored visualRegion. If we pump
  1496.      * the core on such an event, it may result in a timesync
  1497.      * and a draw. Since the visualRegiom may be set to a wrong value,
  1498.      * nothing may be displayed.
  1499.      */
  1500.     if (pEvent->event == nullEvent)
  1501.     {
  1502.         Timeline::CallAllTimeSyncs();
  1503.     }        
  1504. #else
  1505.     if (m_pSiteEventHandler)
  1506.     {
  1507.         m_pSiteEventHandler->EventOccurred(pEvent);
  1508.     }
  1509.     if (!pEvent)
  1510.     {
  1511.         Timeline::CallAllTimeSyncs();
  1512.     }
  1513. #endif
  1514. #elif defined(__TCS__)
  1515.     
  1516. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  1517.     if (!pEvent)
  1518.     {
  1519.         tm1_TCP::process_idle();
  1520.     }
  1521. #endif //HELIX_FEATURE_PLAYBACK_NET
  1522.     
  1523.     if (m_pSiteEventHandler)
  1524.     {
  1525.         m_pSiteEventHandler->EventOccurred(pEvent);
  1526.     }
  1527.     if (!pEvent)
  1528.     {
  1529.         Timeline::CallAllTimeSyncs();
  1530.     }    
  1531. #elif defined (_MACINTOSH) //if def _UNIX
  1532. #define MINIMUM_TIME_BETWEEN_NULL_EVENTS    10
  1533.     static UINT32 ulLastNullEventTime = 0;
  1534.     
  1535.     if (pEvent && pEvent->event == nullEvent)
  1536.     {
  1537.     UINT32 ulCurrentTime = HX_GET_TICKCOUNT();
  1538.     static Rect sLastNullEventClipRect = {0,0,0,0};
  1539.     
  1540.     Rect thisClipRect = {0,0,0,0};
  1541. #ifdef _CARBON
  1542.     GrafPtr thePort = GetQDGlobalsThePort();
  1543.     if (thePort)
  1544.     {
  1545.         RgnHandle clipRgn = ::NewRgn();
  1546.         GetPortClipRegion(thePort, clipRgn);
  1547.         GetRegionBounds(clipRgn, &thisClipRect);
  1548.         ::DisposeRgn(clipRgn);
  1549.     }
  1550. #else
  1551.     if (qd.thePort && qd.thePort->clipRgn)
  1552.     {
  1553.         thisClipRect = (**qd.thePort->clipRgn).rgnBBox;
  1554.     }
  1555. #endif
  1556.     
  1557.     if (!::EqualRect(&sLastNullEventClipRect, &thisClipRect))
  1558.     {
  1559.         sLastNullEventClipRect = thisClipRect;
  1560.         // if it's not equal to the previous clip rectangle, be sure
  1561.         // to pass this null event through so the clip region information
  1562.         // can be propogated if necessary.
  1563.     }
  1564.     else
  1565.     {
  1566.         if (CALCULATE_ELAPSED_TICKS(ulLastNullEventTime, ulCurrentTime) < 
  1567.         MINIMUM_TIME_BETWEEN_NULL_EVENTS)
  1568.             {
  1569.         // ignore a null event.. too many of them!
  1570.         return HXR_OK;
  1571.             }
  1572.     }
  1573.         
  1574.         ulLastNullEventTime = ulCurrentTime;
  1575.     }
  1576.     
  1577.     if (m_pCoreMutex)
  1578.     {
  1579.     m_pCoreMutex->Lock();
  1580.     }
  1581.     LISTPOSITION lPosition = m_PlayerList.GetHeadPosition();
  1582.     HXPlayer* pPlayer;
  1583.     while (lPosition != NULL)
  1584.     {
  1585.     pPlayer = (HXPlayer*) m_PlayerList.GetNext(lPosition);
  1586.     pPlayer->EventOccurred(pEvent);
  1587.     }
  1588.        
  1589. #ifdef HELIX_FEATURE_VIDEO
  1590.     extern ULONG32     gTIMELINE_MUTEX;
  1591.     InterlockedIncrement(&gTIMELINE_MUTEX);
  1592.     CHXSiteManager::EventOccurred(pEvent);
  1593.     InterlockedDecrement(&gTIMELINE_MUTEX);
  1594. #endif
  1595.     
  1596.     static UINT32 ulLastTimeMemoryCompacted = 0;
  1597.     UINT32 ulTickCount = HX_GET_TICKCOUNT();
  1598.     // every thirty seconds, compact memory.
  1599.     if ( CALCULATE_ELAPSED_TICKS( ulLastTimeMemoryCompacted, ulTickCount ) >= 30000 )
  1600.     {
  1601.     HXMM_COMPACT();
  1602.     ulLastTimeMemoryCompacted = ulTickCount;
  1603.     }
  1604.     if (m_pCoreMutex)
  1605.     {
  1606.     m_pCoreMutex->Unlock();
  1607.     }
  1608.     /* Do not pump the core on any other event since the top level
  1609.      * sends fake update events with doctored visualRegion. If we pump
  1610.      * the core on such an event, it may result in a timesync
  1611.      * and a draw. Since the visualRegiom may be set to a wrong value,
  1612.      * nothing may be displayed.
  1613.      */
  1614.     if (pEvent->event == nullEvent)
  1615.     {
  1616.         Timeline::CallAllTimeSyncs();
  1617.     }
  1618. #elif defined(_OPENWAVE) // if defined(_UNIX)
  1619.    if (!pEvent)
  1620.     {
  1621.         Timeline::CallAllTimeSyncs();
  1622.     }
  1623. #endif // _UNIX
  1624.     return HXR_OK;
  1625. }
  1626. #ifdef _UNIX
  1627. /************************************************************************
  1628.  *  Method:
  1629.  *      IHXClientEngine::Select
  1630.  *  Purpose:
  1631.  *      Top level clients under Unix should use this instead of
  1632.  *      select() to select for events.
  1633.  */
  1634. STDMETHODIMP_(INT32)
  1635. HXClientEngine::Select(INT32 n,
  1636.             fd_set* readfds,
  1637.             fd_set* writefds,
  1638.             fd_set* exceptfds,
  1639.             struct timeval* timeout)
  1640. {
  1641.     int s=0;
  1642.     //XXXgfw no need for these selects if we aren't doing network i/o.
  1643.     //Of course, it would be nice for those using this instead of a sleep
  1644.     //to time their callbacks back into the core, that it works...
  1645.     //I guess we can just turn this into a sleep for timeval seconds if
  1646.     //we are not doing any network playback. Of course, if you have a
  1647.     //threaded core it won't hurt to much either way.
  1648. #if defined(HELIX_FEATURE_PLAYBACK_NET)    
  1649.     fd_set real_readfds;
  1650.     fd_set real_writefds;
  1651.     fd_set real_exceptfds;
  1652.     struct timeval tv;
  1653.     static unix_TCP* un = 0;
  1654.     if(!un)
  1655.     {
  1656.         un = new unix_TCP; 
  1657.     }
  1658.     if(readfds)
  1659.     {
  1660.         real_readfds = *readfds;
  1661.     }
  1662.     else
  1663.     {
  1664.         FD_ZERO(&real_readfds);
  1665.     }
  1666.     if(writefds)
  1667.     {
  1668.         real_writefds = *writefds;
  1669.     }
  1670.     else
  1671.     {
  1672.         FD_ZERO(&real_writefds);
  1673.     }
  1674.     if(exceptfds)
  1675.     {
  1676.         real_exceptfds = *exceptfds;
  1677.     }
  1678.     else
  1679.     {
  1680.         FD_ZERO(&real_exceptfds);
  1681.     }
  1682.     if(timeout)
  1683.     {
  1684.         tv = *timeout;
  1685.     }
  1686.     else
  1687.     {
  1688.         /* If no timeout was passed in, and no player adds a timeout,
  1689.            we will not pass a timeout to select()
  1690.         */
  1691.         tv.tv_sec = -1;
  1692.         tv.tv_usec = -1;
  1693.     }
  1694.     /* It is assumed that the networking code does not care about select
  1695.        timeouts, so it is only asked for socket info.
  1696.     */
  1697.     un->add_select((int*)&n, &real_readfds, &real_writefds, &real_exceptfds);
  1698.     CHXSimpleList::Iterator lIterator   = m_PlayerList.Begin();
  1699.     LISTPOSITION lPosition = m_PlayerList.GetHeadPosition();
  1700.     HXPlayer* pPlayer;
  1701.     while (lPosition != NULL)
  1702.     {
  1703.         pPlayer = (HXPlayer*) m_PlayerList.GetNext(lPosition);
  1704.         pPlayer->CollectSelectInfo(&n, 
  1705.                                    &real_readfds,
  1706.                                    &real_writefds,
  1707.                                    &real_exceptfds,
  1708.                                    &tv);
  1709.     }
  1710.     
  1711.     for(lIterator = m_select_callbacks->Begin();
  1712.         lIterator != m_select_callbacks->End();
  1713.         ++lIterator)
  1714.     {
  1715.         CHXSelectCallback* scb = (CHXSelectCallback*)(*lIterator);
  1716.         if(scb->m_flags & PNAIO_READ)
  1717.             FD_SET(scb->m_lFileDescriptor, &real_readfds);
  1718.         if(scb->m_flags & PNAIO_WRITE)
  1719.             FD_SET(scb->m_lFileDescriptor, &real_writefds);
  1720.     
  1721.         if(scb->m_flags & PNAIO_EXCEPTION)
  1722.             FD_SET(scb->m_lFileDescriptor, &real_exceptfds);
  1723.         if(scb->m_lFileDescriptor > n)
  1724.             n = scb->m_lFileDescriptor + 1;
  1725.     }
  1726.     UINT32 ulEventTime = 0;
  1727.     if(m_pScheduler)
  1728.     {
  1729.         if(m_pScheduler->GetNextEventDueTimeDiff(ulEventTime))
  1730.         {
  1731.             if(ulEventTime < ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)))
  1732.             {
  1733.                 tv.tv_sec = ulEventTime / 1000;
  1734.                 tv.tv_usec = (ulEventTime % 1000) * 1000;
  1735.             }
  1736.         }
  1737.     }
  1738.     if(timeout || (tv.tv_sec >= 0 && tv.tv_usec >= 0))
  1739.         s = ::select(n, &real_readfds, &real_writefds, &real_exceptfds, &tv);
  1740.     else
  1741.         s = ::select(n, &real_readfds, &real_writefds, &real_exceptfds, 0);
  1742.     un->process_select(n, &real_readfds, &real_writefds, &real_exceptfds);
  1743.     lIterator   = m_PlayerList.Begin();
  1744.     lPosition = m_PlayerList.GetHeadPosition();
  1745.     
  1746.     while (lPosition != NULL)
  1747.     {
  1748.         pPlayer = (HXPlayer*) m_PlayerList.GetNext(lPosition);
  1749.         pPlayer->ProcessSelect(&n, 
  1750.                                &real_readfds,
  1751.                                &real_writefds,
  1752.                                &real_exceptfds,
  1753.                                &tv);
  1754.     }
  1755.     
  1756.     for(lIterator = m_select_callbacks->Begin();
  1757.         lIterator != m_select_callbacks->End();
  1758.         ++lIterator)
  1759.     {
  1760.         CHXSelectCallback* scb = (CHXSelectCallback*)(*lIterator);
  1761.         if((scb->m_flags & PNAIO_READ) && 
  1762.            FD_ISSET(scb->m_lFileDescriptor, &real_readfds))
  1763.         {
  1764.             scb->m_pCallback->Func();
  1765.         }
  1766.         if((scb->m_flags & PNAIO_WRITE) &&
  1767.            FD_ISSET(scb->m_lFileDescriptor, &real_writefds))
  1768.         {
  1769.             scb->m_pCallback->Func();
  1770.         }
  1771.         if((scb->m_flags & PNAIO_EXCEPTION) &&
  1772.            FD_ISSET(scb->m_lFileDescriptor, &real_exceptfds))
  1773.         {
  1774.             scb->m_pCallback->Func();
  1775.         }
  1776.     }
  1777.     ulEventTime = 0;
  1778.     if(m_pScheduler)
  1779.     {
  1780.         if(m_pScheduler->GetNextEventDueTimeDiff(ulEventTime))
  1781.         {
  1782.             if(ulEventTime == 0)
  1783.             {
  1784.                 Timeline::CallAllTimeSyncs();
  1785.             }
  1786.         }
  1787.     }
  1788. #else
  1789.     s = ::select(0, NULL, NULL, NULL, timeout);
  1790. #endif //HELIX_FEATURE_PLAYBACK_NET    
  1791.     return s;
  1792. }
  1793. STDMETHODIMP
  1794. HXClientEngine::Add(IHXCallback* pCallback,
  1795.                INT32 lFileDescriptor,
  1796.                UINT32 ulFlags)
  1797. {
  1798.     CHXSelectCallback* scb = new CHXSelectCallback(pCallback,
  1799.                            lFileDescriptor,
  1800.                            ulFlags);
  1801.     m_select_callbacks->AddTail(scb);
  1802.     return HXR_OK;
  1803. }
  1804. STDMETHODIMP
  1805. HXClientEngine::Remove(INT32 lFileDescriptor,
  1806.             UINT32 ulFlags)
  1807. {
  1808.     CHXSimpleList::Iterator i;
  1809.     CHXSelectCallback* scb;
  1810.     for(i = m_select_callbacks->Begin();
  1811.     i != m_select_callbacks->End();
  1812.     ++i)
  1813.     {
  1814.     scb = (CHXSelectCallback*)(*i);
  1815.     if(scb->m_lFileDescriptor == lFileDescriptor && 
  1816.        scb->m_flags == ulFlags)
  1817.     {
  1818.         m_select_callbacks->RemoveAt(m_select_callbacks->Find(scb));
  1819.         delete scb;
  1820.         return HXR_OK;
  1821.     }
  1822.     }
  1823.     return HXR_FAIL;
  1824. }
  1825. #endif /* _UNIX */
  1826. /*
  1827.  *  IHXMimeTypeMapper methods
  1828.  */
  1829. STDMETHODIMP HXClientEngine::MapFromExtToMime
  1830. (
  1831.     const char*     /*IN*/  pExtension,
  1832.     REF(const char*)    /*OUT*/ pMimeType
  1833. )
  1834. {
  1835.     HX_RESULT hr = HXR_OK;
  1836. #if defined(HELIX_FEATURE_PLUGINHANDLER2)
  1837.     if (!m_pPlugin2Handler)
  1838.     {
  1839.     hr = HXR_FAIL;
  1840.     goto cleanup;
  1841.     }
  1842.     // try to map from the normal file format plugins
  1843.     
  1844.     UINT32 unPluginIndex; 
  1845.     IHXValues* pValues; 
  1846.     IHXBuffer* pBuffer; 
  1847.     // Note that the ref count of the buffer is not increased this is bad. But should be OK in 
  1848.     // this case.
  1849.     if (HXR_OK == m_pPlugin2Handler->FindIndexUsingStrings(PLUGIN_CLASS, PLUGIN_FILEFORMAT_TYPE, 
  1850.     PLUGIN_FILEEXTENSIONS, (char*)pExtension, NULL, NULL, unPluginIndex))
  1851.     {
  1852.     m_pPlugin2Handler->GetPluginInfo(unPluginIndex, pValues);
  1853.     if (HXR_OK == pValues->GetPropertyCString(PLUGIN_FILEMIMETYPES, pBuffer))
  1854.     {
  1855.         pMimeType = (const char*)pBuffer->GetBuffer();
  1856.         pBuffer->Release();
  1857.     }
  1858.     pValues->Release();
  1859.     }
  1860. cleanup:
  1861.     return hr;
  1862. #else
  1863.     return HXR_FAIL;
  1864. #endif /* HELIX_FEATURE_PLUGINHANDLER2 */
  1865. }
  1866. /*
  1867.  * IHXClientEngineSetup methods
  1868.  */
  1869. /************************************************************************
  1870.  *  Method:
  1871.  *      IHXClientEngineSetup::Setup
  1872.  *  Purpose:
  1873.  *      Top level clients use this interface to over-ride certain basic 
  1874.  *      interfaces are: IHXPreferences, IHXHyperNavigate
  1875.  */
  1876. STDMETHODIMP HXClientEngine::Setup(IUnknown* pContext)
  1877. {
  1878.     if (!pContext || m_bInitialized) 
  1879.     return HXR_UNEXPECTED;
  1880.     
  1881.     /* Make sure this is called before any player is created */
  1882.     HX_ASSERT(GetPlayerCount() == 0);
  1883.     if (GetPlayerCount() > 0)
  1884.     {
  1885.     return HXR_UNEXPECTED;
  1886.     }
  1887.     /* Override Default objects */
  1888.     IHXCommonClassFactory* pFactory = 0;
  1889.     if (HXR_OK == pContext->QueryInterface(IID_IHXCommonClassFactory, (void**) &pFactory))
  1890.     {
  1891.     HX_RELEASE(m_pCommonClassFactoryOverride);
  1892.     m_pCommonClassFactoryOverride = pFactory;
  1893.     }
  1894.     IHXPreferences* pPreferences = 0;
  1895.     if (HXR_OK == pContext->QueryInterface(IID_IHXPreferences, (void**) &pPreferences))
  1896.     {
  1897.     HX_RELEASE(m_pPreferences);
  1898.     m_pPreferences = pPreferences;
  1899. #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
  1900.     /* Hand over the new preferences to hyper-navigation module */
  1901.     m_pOrigHyperNavigate->Init((IUnknown*) (IHXClientEngine*)this);
  1902. #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
  1903.     }
  1904. #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
  1905.     IHXHyperNavigate* pHyperNavigate = 0;
  1906.     if (HXR_OK == pContext->QueryInterface(IID_IHXHyperNavigate, (void**) &pHyperNavigate))
  1907.     {
  1908.     HX_RELEASE(m_pHyperNavigate);
  1909.     m_pHyperNavigate = pHyperNavigate;
  1910.     }
  1911. #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
  1912. #ifdef _UNIX
  1913.     IHXAsyncIOSelection* pAsyncIOSelection = 0;
  1914.     if (HXR_OK == pContext->QueryInterface(IID_IHXAsyncIOSelection, (void**) &pAsyncIOSelection))
  1915.     {
  1916.     HX_RELEASE(m_pAsyncIOSelection);
  1917.     m_pAsyncIOSelection = pAsyncIOSelection;
  1918.     }
  1919. #endif
  1920. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  1921.     IHXNetworkServices* pNetworkServices = NULL;
  1922.     if (HXR_OK == pContext->QueryInterface(IID_IHXNetworkServices, (void**) &pNetworkServices))
  1923.     {
  1924.     HX_RELEASE(m_pNetworkServices);
  1925.     m_pNetworkServices = pNetworkServices;
  1926.     }
  1927. #endif /* HELIX_FEATURE_PLAYBACK_NET */
  1928. #if defined(HELIX_FEATURE_SYSTEMREQUIRED)
  1929.     IHXSystemRequired* pSystemRequired = NULL;
  1930.     if (HXR_OK == pContext->QueryInterface(IID_IHXSystemRequired, (void**) &pSystemRequired))
  1931.     {
  1932.     HX_RELEASE(m_pSystemRequired);
  1933.     m_pSystemRequired = pSystemRequired;
  1934.     }
  1935. #endif /* HELIX_FEATURE_SYSTEMREQUIRED */
  1936.     IHXMultiPlayPauseSupport* pMPPSupport = NULL;
  1937.     if (HXR_OK == pContext->QueryInterface(IID_IHXMultiPlayPauseSupport, (void**) &pMPPSupport))
  1938.     {
  1939.     HX_RELEASE(m_pMultiPlayPauseSupport);
  1940.     m_pMultiPlayPauseSupport = pMPPSupport;
  1941.     }
  1942.     _Initialize();
  1943.     
  1944.     return HXR_OK;
  1945. }
  1946. /*
  1947.  *   HXClientEngine methods
  1948.  */
  1949. void HXClientEngine::Close()
  1950. {    
  1951.     /* There should not be any outstanding players */
  1952.     HX_ASSERT(m_PlayerList.GetCount() == 0);
  1953. #if defined(HELIX_FEATURE_PREFERENCES)
  1954.     // nhart: if prefs have been overridden, we want to release them before we
  1955.     // unload our plugins and restore the original prefs.
  1956.     if (m_pPreferences != m_pOrigPreferences)
  1957.     {
  1958. HX_RELEASE(m_pPreferences);
  1959. m_pPreferences = m_pOrigPreferences;
  1960. HX_ADDREF(m_pPreferences);
  1961.     }
  1962. #endif /* HELIX_FEATURE_PREFERENCES */
  1963. #if defined _UNIX && !defined _VXWORKS
  1964.     HX_RELEASE(m_pSiteEventHandler);
  1965. #endif
  1966.     
  1967.     CHXSimpleList::Iterator ndxPlayer = m_PlayerList.Begin();
  1968.     for (; ndxPlayer != m_PlayerList.End(); ++ndxPlayer)
  1969.     {
  1970.     HXPlayer* pHXPlayer = (HXPlayer*) (*ndxPlayer);
  1971.     m_pPlayerSinkControl->PlayerClosed(pHXPlayer);
  1972.     pHXPlayer->ClosePlayer();
  1973.         pHXPlayer->Release();
  1974.     }
  1975.     m_PlayerList.RemoveAll();
  1976.     if (m_pPlayerSinkControl)
  1977.         m_pPlayerSinkControl->Terminate();
  1978.     HX_RELEASE(m_pPlayerSinkControl);
  1979.     if (m_bIsSchedulerStarted)
  1980.     {
  1981.     m_pScheduler->StopScheduler();
  1982. #if defined(HELIX_FEATURE_OPTIMIZED_SCHEDULER)
  1983.     if (m_pOptimizedScheduler)
  1984.     {
  1985. m_pOptimizedScheduler->StopScheduler();
  1986.     }
  1987. #endif /* HELIX_FEATURE_OPTIMIZED_SCHEDULER */
  1988.     m_bIsSchedulerStarted = FALSE;
  1989.     }    
  1990.     
  1991. #if defined(HELIX_FEATURE_AUDIO)
  1992.     if (m_pAudioSession)
  1993.     {
  1994.     m_pAudioSession->Close();
  1995.     HX_RELEASE(m_pAudioSession);
  1996.     }
  1997. #endif /* HELIX_FEATURE_AUDIO */
  1998. #if defined(HELIX_FEATURE_REGISTRY)
  1999.     if (m_pRegistry)
  2000.     {
  2001.     // remove the registry
  2002.     if (m_unRegistryID)
  2003.     {
  2004.         m_pRegistry->DeleteById(m_unRegistryID);
  2005.         m_unRegistryID = 0;
  2006.     }
  2007.     m_pRegistry->Close();
  2008.     HX_RELEASE(m_pRegistry);
  2009.     }
  2010. #endif /* HELIX_FEATURE_REGISTRY */
  2011. #if defined(HELIX_FEATURE_PAC)
  2012.     if (m_pProxyAutoConfig)
  2013.     {
  2014.         m_pProxyAutoConfig->Close();
  2015.         HX_RELEASE(m_pProxyAutoConfig);
  2016.     }
  2017. #endif /* HELIX_FEATURE_PAC */
  2018. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  2019.     HX_RELEASE(m_pNetworkServices);
  2020.     if (m_pOrigNetworkServices)
  2021.     {
  2022.     m_pOrigNetworkServices->Close();    
  2023.     HX_RELEASE(m_pOrigNetworkServices);
  2024.     }    
  2025. #endif /* HELIX_FEATURE_PLAYBACK_NET */
  2026. #ifdef _MEDIUM_BLOCK
  2027.     if (m_pAllocator)
  2028.     {
  2029.     m_pAllocator->SetScheduler(NULL);
  2030.     }
  2031. #endif /* _MEDIUM_BLOCK */
  2032.     HX_RELEASE(m_pScheduler);
  2033. #if defined(HELIX_FEATURE_OPTIMIZED_SCHEDULER)
  2034.     HX_RELEASE(m_pOptimizedScheduler);
  2035. #endif /* HELIX_FEATURE_OPTIMIZED_SCHEDULER */
  2036.     if (m_pCommonClassFactory)
  2037.     {
  2038.     m_pCommonClassFactory->Close();
  2039.     m_pCommonClassFactory->Release();
  2040.     m_pCommonClassFactory = NULL;
  2041.     }
  2042. #if defined(HELIX_FEATURE_ASM)
  2043.     HX_RELEASE(m_pASM);
  2044. #endif /* HELIX_FEATURE_ASM */
  2045. #if defined(HELIX_FEATURE_META)
  2046.     HX_RELEASE(m_pValidator);
  2047. #endif /* HELIX_FEATURE_META */
  2048. #if defined(HELIX_FEATURE_RESOURCEMGR)
  2049.     HX_RELEASE(m_pExternalResourceManager);
  2050.     HX_DELETE(m_pResMgr);
  2051. #endif /* HELIX_FEATURE_RESOURCEMGR */
  2052. #if defined(HELIX_FEATURE_XMLPARSER)
  2053.     HX_RELEASE(m_pXMLParser);
  2054. #endif /* HELIX_FEATURE_XMLPARSER */
  2055. #if defined (HELIX_FEATURE_COOKIES)
  2056.     HX_RELEASE(m_pCookiesHelper);
  2057. #endif /* HELIX_FEATURE_COOKIES */
  2058. #if defined(HELIX_FEATURE_VIEWSOURCE)
  2059.     HX_RELEASE(m_pViewSource);
  2060. #endif /* HELIX_FEATURE_VIEWSOURCE */
  2061. #if defined(HELIX_FEATURE_SYSTEMREQUIRED)
  2062.     HX_RELEASE(m_pSystemRequired);
  2063. #endif /* HELIX_FEATURE_SYSTEMREQUIRED */
  2064.     HX_RELEASE(m_pMultiPlayPauseSupport);
  2065. #if defined(HELIX_FEATURE_COOKIES)
  2066.     if (m_pCookies)
  2067.     {
  2068.     m_pCookies->Close();
  2069.     HX_RELEASE(m_pCookies);
  2070.     }
  2071. #endif /* defined(HELIX_FEATURE_COOKIES) */
  2072. #if defined(HELIX_FEATURE_PROXYMGR)
  2073.     if (m_pProxyManager)
  2074.     {
  2075.     m_pProxyManager->Close();
  2076.     HX_RELEASE(m_pProxyManager);
  2077.     }
  2078. #endif /* HELIX_FEATURE_PROXYMGR */
  2079. #if defined(HELIX_FEATURE_SMARTERNETWORK)
  2080.     if (m_pPreferredTransportManager)
  2081.     {
  2082.     m_pPreferredTransportManager->Close();
  2083.     HX_RELEASE(m_pPreferredTransportManager);
  2084.     }
  2085. #endif /* HELIX_FEATURE_SMARTERNETWORK */
  2086. #if defined(HELIX_FEATURE_OVERLAYMGR)
  2087.     if (m_pOverlayManager)
  2088.     {
  2089.         m_pOverlayManager->Close();
  2090.         HX_RELEASE(m_pOverlayManager);
  2091.     }
  2092. #endif /* HELIX_FEATURE_OVERLAYMGR */
  2093. #if defined(HELIX_FEATURE_AUTHENTICATION)
  2094.     if (m_pCredentialsCache)
  2095.     {
  2096.     m_pCredentialsCache->Close();
  2097.     HX_RELEASE(m_pCredentialsCache);
  2098.     }
  2099. #endif /* HELIX_FEATURE_AUTHENTICATION */
  2100. #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
  2101.     HX_RELEASE(m_pHyperNavigate);
  2102. #ifndef _WINCE
  2103.     if (m_pOrigHyperNavigate)
  2104.     {
  2105.       /* This solution is to call DdeUninitialize on the main app thread
  2106.        * instead of the HyperNavigation thread. 
  2107.        * Calling DdeUninitialize on the hyper navigation thread results
  2108.        * in a deadlock in embedded players.
  2109.        *
  2110.        * With this solution, we do not cleanly shutdown DDE. 
  2111.        * Calls to DdeFreeStringHandle and DdeUninitialize (called from 
  2112.        * our function DDEShutdown() fail since 
  2113.        * DDEInitialize was called on a different thread.
  2114.        *
  2115.        * It does cleanup the hidden windows even though DdeUninitialize 
  2116.        * returns FALSE!, so this solution is SAFE.
  2117.        */
  2118. #if (defined (_WINDOWS) || defined (_WIN32))
  2119.     DDEStartup();
  2120. #endif /*_WINDOWS*/
  2121.     m_pOrigHyperNavigate->Stop();
  2122.     HX_RELEASE(m_pOrigHyperNavigate);
  2123. #if (defined (_WINDOWS) || defined (_WIN32))
  2124.     DDEShutdown();
  2125. #endif /*_WINDOWS*/
  2126.     }
  2127. #endif /*_WINCE*/
  2128. #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
  2129. #if defined(HELIX_FEATURE_CORECOMM)
  2130.     HX_DELETE(m_pCoreComm);
  2131. #endif /* HELIX_FEATURE_CORECOMM */
  2132. #if defined(HELIX_FEATURE_NETINTERFACES)
  2133.     if (m_pNetInterfaces)
  2134.     {
  2135.     m_pNetInterfaces->Close();
  2136.     HX_RELEASE(m_pNetInterfaces);
  2137.     }
  2138. #endif /* HELIX_FEATURE_NETINTERFACES */
  2139.     if (m_pSingleLoadPlugins)
  2140.     {
  2141.     // Delete our list of single loaded plugins.
  2142.     CHXSimpleList::Iterator i;
  2143.     for(i = m_pSingleLoadPlugins->Begin(); i != m_pSingleLoadPlugins->End(); ++i)
  2144.     {
  2145.         IHXPlugin* pPlugin = (IHXPlugin*)(*i);
  2146.         pPlugin->Release();
  2147.     }
  2148.     delete m_pSingleLoadPlugins;
  2149.     m_pSingleLoadPlugins = 0;
  2150.     }
  2151.     if(m_pPlugin2Handler)
  2152.     {
  2153. #if defined(HELIX_FEATURE_PLUGINHANDLER2)
  2154.     m_pPlugin2Handler->Close();
  2155. #endif /* HELIX_FEATURE_PLUGINHANDLER2 */
  2156.     HX_RELEASE(m_pPlugin2Handler);
  2157.     }
  2158. #ifdef _WIN32
  2159.     HXCloseLibrary();
  2160. #endif
  2161.     HX_DELETE(m_pCoreMutex);
  2162. #if defined(_MACINTOSH) && defined(_CARBON) && defined(THREADS_SUPPORTED)
  2163.     HX_DELETE(m_pMacBlitMutex);
  2164. #endif
  2165. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  2166. //#if 0
  2167. #ifdef THREADS_SUPPORTED
  2168.     ThreadEngine::DestroyThreadEngine();
  2169. #elif defined(_UNIX_THREADED_NETWORK_IO)
  2170.     if( m_bNetworkThreading )
  2171.         ThreadEngine::DestroyThreadEngine();
  2172. #endif /*THREADS_SUPPORTED*/
  2173. #endif /* HELIX_FEATURE_PLAYBACK_NET */
  2174. #ifdef _MACINTOSH
  2175. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  2176.     conn::close_drivers(NULL);
  2177. #endif
  2178. #endif
  2179.     CHXBuffer::ReleaseAllocator();
  2180. #ifdef _MEDIUM_BLOCK
  2181.     HX_RELEASE(m_pAllocator);
  2182. #endif /* _MEDIUM_BLOCK */
  2183. #if defined(HELIX_FEATURE_PREFERENCES)
  2184.     // XXXKB HXPlayer uses preferences on destruction;
  2185.     // Since Close() will nuke the underlying implementation
  2186.     // regardless of ref. count, we need to place this last:
  2187.     HX_RELEASE(m_pPreferences);
  2188.     if (m_pOrigPreferences)
  2189.     {
  2190. #if !defined(HELIX_FEATURE_NO_INTERNAL_PREFS)
  2191.     m_pOrigPreferences->Close();
  2192. #endif /* !defined(HELIX_FEATURE_NO_INTERNAL_PREFS) */
  2193.     HX_RELEASE(m_pOrigPreferences);
  2194.     }
  2195. #endif /* HELIX_FEATURE_PREFERENCES */
  2196. }
  2197. /*
  2198. * IRMAInterruptState methods
  2199. */
  2200. // xxxbobclark There's a subtle difference between the Mac implementation
  2201. // and the other platforms' implementation. Here's what Rahul has to say
  2202. // about the matter:
  2203. // a) AtInterruptTime = (CurrentThread != SystemThread ? TRUE : FALSE)
  2204. // b) AtInterruptTime = (CurrentThread == CoreThread ? TRUE : FALSE)
  2205. //
  2206. // SystemThread = Thread that the core was loaded on. i.e. Main App Thread
  2207. // Core Thread = Internal Thread spawned by the core to do core processing.
  2208. //
  2209. // The actual definition of AtInterruptTime is supposed to be a) but it somehow is coded
  2210. // as b), at least for Windows. The reason it has worked till now is because there really
  2211. // are just two threads on Windows on which the core processing is done, so even with b),
  2212. // if the current thread is NOT core thread, then it must be system thread.
  2213. //
  2214. // Renderers (and callbacks) that DO NOT claim to be interrupt safe are supposed to be
  2215. // called ONLY on the SystemThread.
  2216. //
  2217. // So, on Mac, since IsMacInCooperativeThread is equivalent to being at system time,
  2218. //
  2219. // AtInterruptTime = !IsMacInCooperativeThread().
  2220. STDMETHODIMP_(BOOL)
  2221. HXClientEngine::AtInterruptTime()
  2222. {
  2223. #if defined(_MACINTOSH)
  2224.     return !IsMacInCooperativeThread();
  2225. #elif defined(_MAC_UNIX)
  2226.     return (::MPTaskIsPreemptive(::MPCurrentTaskID()));
  2227. #elif defined (_WIN32) || defined(THREADS_SUPPORTED)
  2228.     return m_pScheduler ? m_pScheduler->IsAtInterruptTime() : FALSE;
  2229. #else
  2230. return FALSE;
  2231. #endif 
  2232. }
  2233. STDMETHODIMP 
  2234. HXClientEngine::EnterInterruptState()
  2235. {
  2236. #ifdef _MACINTOSH
  2237. #ifndef _MAC_MACHO
  2238.     HXMM_INTERRUPTON();
  2239. #endif
  2240. #endif 
  2241.     return HXR_OK;
  2242. }
  2243. STDMETHODIMP 
  2244. HXClientEngine::LeaveInterruptState()
  2245. {
  2246. #ifdef _MACINTOSH
  2247. #ifndef _MAC_MACHO
  2248.     HXMM_INTERRUPTOFF();
  2249. #endif
  2250. #endif 
  2251.     return HXR_OK;
  2252. }
  2253. STDMETHODIMP 
  2254. HXClientEngine::EnableInterrupt(BOOL   bEnable)
  2255. {
  2256.     /* Make sure all the players are in a stopped state */
  2257.     CHXSimpleList::Iterator ndx = m_PlayerList.Begin();
  2258.     for (; ndx != m_PlayerList.End(); ++ndx)
  2259.     {
  2260.     HXPlayer* pHXPlayer = (HXPlayer*) (*ndx);
  2261.     HX_ASSERT(pHXPlayer->IsPlaying() == FALSE);
  2262.     if (pHXPlayer->IsPlaying())
  2263.     {
  2264.         return HXR_FAILED;
  2265.     }
  2266.     }
  2267.     m_bUseCoreThreadExternallySet = TRUE;
  2268. #ifdef _MACINTOSH
  2269.     /* Currently Interrupts are ALWAYS enabled on Mac */
  2270.     if (!bEnable)
  2271.     {
  2272.     return HXR_FAILED;
  2273.     }
  2274.     return HXR_OK;
  2275. #elif THREADS_SUPPORTED
  2276.     if (!m_bInitialized)
  2277.     {
  2278.     m_bUseCoreThread = bEnable;
  2279.         
  2280.     }
  2281.     else if (m_bUseCoreThread != bEnable)
  2282.     {
  2283.     m_bUseCoreThread = bEnable;
  2284.     InitializeThreadedObjects();
  2285.     }
  2286.     return HXR_OK;
  2287. #else
  2288.     return HXR_FAILED;
  2289. #endif
  2290. }
  2291. STDMETHODIMP_(BOOL) 
  2292. HXClientEngine::IsInterruptEnabled()
  2293. {
  2294. #ifdef _MACINTOSH
  2295.     return TRUE;    //HXMM_INTERRUPTOFF();
  2296. #elif THREADS_SUPPORTED
  2297.     return m_bUseCoreThread;
  2298. #else
  2299.     return FALSE;
  2300. #endif
  2301. }
  2302. void
  2303. HXClientEngine::InitializeThreadedObjects()
  2304. {
  2305. //XXXgfw Right now UNIX uses forks to get threaded hypernave done. It
  2306. //also allows programs to be executed that way which is not supported
  2307. //by our threaded hypernav class. We need to look at extending that
  2308. //class or maybe the UNIX TLC does not need that any more???
  2309. #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
  2310. #if !defined(_WINCE) && !defined(_UNIX)
  2311.     m_pOrigHyperNavigate->UseThread(m_bUseCoreThread);
  2312. #endif
  2313. #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
  2314.     if (m_bIsSchedulerStarted)
  2315.     {
  2316.     m_pScheduler->StopScheduler();
  2317.     }
  2318.     m_pScheduler->SetCoreMutex(m_pCoreMutex);
  2319.     m_pScheduler->SetInterrupt(m_bUseCoreThread);
  2320.     m_LastError = m_pScheduler->StartScheduler();
  2321.     m_bIsSchedulerStarted = TRUE;
  2322.     CHXSimpleList::Iterator ndx = m_PlayerList.Begin();
  2323.     for (; ndx != m_PlayerList.End(); ++ndx)
  2324.     {
  2325.     HXPlayer* pHXPlayer = (HXPlayer*) (*ndx);
  2326.     pHXPlayer->SetInterrupt(m_bUseCoreThread);
  2327.     }
  2328. #ifdef _UNIX    
  2329.     //See if we have network threading turned on for unix
  2330.     ReadPrefBOOL(m_pPreferences, "NetworkThreading", m_bNetworkThreading); 
  2331. #endif
  2332. }
  2333. void        
  2334. HXClientEngine::InitializeRegistry()
  2335. {
  2336. #if defined(HELIX_FEATURE_REGISTRY)
  2337.     IHXBuffer* pBuffer = NULL;
  2338.     CHXString   strTemp;
  2339.     // If there has been an error just return
  2340.     if (m_LastError)
  2341.     return;
  2342.     // create registry entry for statistics
  2343.     m_unRegistryID = m_pRegistry->AddComp("Statistics");
  2344.     // Preferences that TLC's can override are stored in here
  2345.     m_pRegistry->AddComp(HXREGISTRY_PREFPROPNAME);
  2346.     // generate client ID
  2347.     // Get the platform information for use in the client ID
  2348.     strTemp.Format("%s.%s",HXREGISTRY_PREFPROPNAME,CLIENT_ID_REGNAME);
  2349.     if(m_pRegistry->GetStrByName(strTemp,pBuffer) != HXR_OK)
  2350.     {
  2351.     HXVERSIONINFO verInfo;
  2352.     HXGetWinVer(&verInfo);
  2353.     // Encode the client ID with the pieces of interest.
  2354.     const char* pszClientID = HXGetVerEncodedName
  2355.                         (&verInfo,
  2356.                         PRODUCT_ID,
  2357.                         TARVER_STRING_VERSION,
  2358.                         LANGUAGE_CODE,
  2359.                         "RN01");
  2360.     // Set clientID
  2361.     pBuffer = CreateBufferAndSetToString(pszClientID);
  2362.     m_pRegistry->AddStr(strTemp,pBuffer);
  2363.     }
  2364.     HX_RELEASE(pBuffer);
  2365.     // RegionData
  2366.     strTemp.Format("%s.%s",HXREGISTRY_PREFPROPNAME,"RegionData");
  2367.     if(m_pRegistry->GetStrByName(strTemp,pBuffer) != HXR_OK)
  2368.     {
  2369.     pBuffer = CreateBufferAndSetToString("0");
  2370.     m_pRegistry->AddStr(strTemp,pBuffer);
  2371.     }
  2372.     HX_RELEASE(pBuffer);
  2373.     // UserAddress
  2374.     strTemp.Format("%s.%s",HXREGISTRY_PREFPROPNAME,"UserAddress");
  2375.     if(m_pRegistry->GetStrByName(strTemp,pBuffer) != HXR_OK)
  2376.     {
  2377.     pBuffer = CreateBufferAndSetToString("");
  2378.     m_pRegistry->AddStr(strTemp,pBuffer);
  2379.     }
  2380.      
  2381.     HX_RELEASE(pBuffer);
  2382.     // Title
  2383.     strTemp.Format("%s.%s",HXREGISTRY_PREFPROPNAME,"Title");
  2384.     if(m_pRegistry->GetStrByName(strTemp,pBuffer) != HXR_OK)
  2385.     {
  2386.     pBuffer = CreateBufferAndSetToString("");
  2387.     m_pRegistry->AddStr(strTemp,pBuffer);
  2388.     }
  2389.     HX_RELEASE(pBuffer);
  2390. #ifdef _WINDOWS
  2391.     INT16 nLangId = LANGIDFROMLCID(GetSystemDefaultLCID());
  2392. #else
  2393.     INT16 nLangId = MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US);
  2394. #endif // _WINDOWS
  2395.     // LangID
  2396.     strTemp.Format("%s.%s",HXREGISTRY_PREFPROPNAME,"LangID");
  2397.     if(m_pRegistry->GetStrByName(strTemp,pBuffer) != HXR_OK)
  2398.     {
  2399.     CHXString strLangID;
  2400.     strLangID.Format("%hd",nLangId);
  2401.     pBuffer = CreateBufferAndSetToString(strLangID);
  2402.     m_pRegistry->AddStr(strTemp,pBuffer);
  2403.     }
  2404.     HX_RELEASE(pBuffer);
  2405. #ifndef _WINCE
  2406.     // Language
  2407.     strTemp.Format("%s.%s",HXREGISTRY_PREFPROPNAME,"Language");
  2408.     if(m_pRegistry->GetStrByName(strTemp,pBuffer) != HXR_OK)
  2409.     {
  2410.     CHXString strLanguage;
  2411.     strLanguage = CHXLang::GetISO639(CHXLang::FindClosest(nLangId));
  2412.     pBuffer = CreateBufferAndSetToString(strLanguage);
  2413.     m_pRegistry->AddStr(strTemp,pBuffer);
  2414.     }
  2415. #endif
  2416.     HX_RELEASE(pBuffer);
  2417. #endif /* HELIX_FEATURE_REGISTRY */
  2418. }
  2419. IHXBuffer*
  2420. HXClientEngine::CreateBufferAndSetToString(const char* pStr)
  2421. {
  2422.     IHXBuffer* lpBuffer = (IHXBuffer*)new CHXBuffer();
  2423.     if (lpBuffer)
  2424.     {
  2425.     lpBuffer->AddRef();
  2426.     lpBuffer->Set((const unsigned char*)pStr,strlen(pStr)+1);
  2427.     }
  2428.     return lpBuffer;
  2429. }
  2430. /*
  2431.  * IHXShutDownEverything methods
  2432.  */
  2433. /************************************************************************
  2434.  *  Method:
  2435.  *      IHXShutDownEverything::ShutDown
  2436.  *  Purpose:
  2437.  *      Shutdown all the renderers/fileformats
  2438.  *
  2439.  */
  2440. STDMETHODIMP
  2441. HXClientEngine::ShutDown(THIS)
  2442. {
  2443.     CHXSimpleList::Iterator ndxPlayer = m_PlayerList.Begin();
  2444.     for (; ndxPlayer != m_PlayerList.End(); ++ndxPlayer)
  2445.     {
  2446.     HXPlayer* pHXPlayer = (HXPlayer*) (*ndxPlayer);
  2447.     pHXPlayer->ShutDown();
  2448.     }
  2449. #if defined(HELIX_FEATURE_META)
  2450.     if (m_pValidator)
  2451.     {
  2452.     m_pValidator->RefreshProtocols();
  2453.     }
  2454. #endif /* HELIX_FEATURE_META */
  2455.     return HXR_OK;
  2456. }
  2457. /************************************************************************
  2458.  *  Method:
  2459.  *      IHXShutDownEverything::StopAllOtherPlayers
  2460.  *  Purpose:
  2461.  *      Shutdown all players
  2462.  *
  2463.  */
  2464. STDMETHODIMP
  2465. HXClientEngine::StopAllOtherPlayers(THIS)
  2466. {
  2467. #if defined(HELIX_FEATURE_CORECOMM)
  2468.     if (m_pCoreComm)
  2469.     {
  2470.     return m_pCoreComm->StopAllOtherAudioPlayers();
  2471.     }
  2472. #endif /* HELIX_FEATURE_CORECOMM */
  2473.     return HXR_OK;
  2474. }
  2475. /************************************************************************
  2476.  *  Method:
  2477.  *      IHXShutDownEverything::AskAllOtherPlayersToUnload
  2478.  *  Purpose:
  2479.  *      Ask all other players in other processes to unload their 
  2480.  *      unused DLLs.
  2481.  */
  2482. STDMETHODIMP
  2483. HXClientEngine::AskAllOtherPlayersToUnload(THIS)
  2484. {
  2485. #if defined(HELIX_FEATURE_CORECOMM)
  2486.     if (m_pCoreComm)
  2487.     {
  2488.     return m_pCoreComm->AskAllOtherPlayersToUnload();
  2489.     }
  2490. #endif /* HELIX_FEATURE_CORECOMM */
  2491.     return HXR_OK;
  2492. }
  2493. /************************************************************************
  2494.  *  Method:
  2495.  *      IHXShutDownEverything::AskAllOtherPlayersToReload
  2496.  *  Purpose:
  2497.  *      Ask all other players in other processes to reload their 
  2498.  *      DLLs.
  2499.  *
  2500.  */
  2501. STDMETHODIMP
  2502. HXClientEngine::AskAllOtherPlayersToReload(THIS)
  2503. {
  2504. #if defined(HELIX_FEATURE_CORECOMM)
  2505.     if (m_pCoreComm)
  2506.     {
  2507.     return m_pCoreComm->AskAllOtherPlayersToReload();
  2508.     }
  2509. #endif /* HELIX_FEATURE_CORECOMM */
  2510.     return HXR_OK;
  2511. }
  2512. /************************************************************************
  2513.  *  Method:
  2514.  *      IHXOverrideDefaultServices::OverrideServices
  2515.  *  Purpose:
  2516.  *      Override default services provided by the G2 system.
  2517.  * 
  2518.  */
  2519. STDMETHODIMP
  2520. HXClientEngine::OverrideServices(IUnknown* pContext)
  2521. {
  2522.     if (!pContext)
  2523.     {
  2524.     return HXR_UNEXPECTED;
  2525.     }
  2526. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  2527.     /* override IHXNetworkServices */
  2528.     IHXNetworkServices* pNetworkServices = NULL;
  2529.     if (pContext->QueryInterface(IID_IHXNetworkServices, (void**) &pNetworkServices)
  2530.         == HXR_OK)
  2531.     {
  2532.     HX_RELEASE(m_pNetworkServices);
  2533.     m_pNetworkServices = pNetworkServices;
  2534.     }
  2535. #endif /* HELIX_FEATURE_PLAYBACK_NET */
  2536.     /* override IHXPreferences */
  2537.     IHXPreferences* pPreferences = NULL;
  2538.     if (pContext->QueryInterface(IID_IHXPreferences, (void**) &pPreferences)
  2539.         == HXR_OK)
  2540.     {
  2541.     HX_RELEASE(m_pPreferences);
  2542.     m_pPreferences = pPreferences;
  2543.     }
  2544.     return HXR_OK;
  2545. }
  2546. /*
  2547.  * IHXErrorMessages methods
  2548.  */
  2549. /************************************************************************
  2550.  *  Method:
  2551.  *      IHXErrorMessages::Report
  2552.  *  Purpose:
  2553.  *      Call this method to report an error, event, or status message.
  2554.  *  Parameters:
  2555.  *
  2556.  *      const UINT8 unSeverity
  2557.  *      Type of report. This value will impact how the player, tool, or
  2558.  *      server will react to the report. Possible values are described 
  2559.  *      above. Depending on the error type, an error message with the 
  2560.  *      RMA code, anda string translation of that code will be displayed. 
  2561.  *      The error dialog includes a "more info" section that displays the
  2562.  *      user code and string, and a link to the more info URL. In the 
  2563.  *      server these messages are logged to the log file.
  2564.  *
  2565.  *      const ULONG32   ulHXCode
  2566.  *      Well known RMA error code. This will be translated to a text
  2567.  *      representation for display in an error dialog box or log file.
  2568.  *
  2569.  *      const ULONG32   ulUserCode
  2570.  *      User specific error code. This will NOT be translated to a text
  2571.  *      representation. This can be any value the caller wants, it will
  2572.  *      be logged or displayed but not interpretted.
  2573.  *
  2574.  *      const char*     pUserString
  2575.  *      User specific error string. This will NOT be translated or 
  2576.  *      modified. This can be any value the caller wants, it will
  2577.  *      be logged or displayed but not interpretted.
  2578.  *
  2579.  *      const char*     pMoreInfoURL
  2580.  *      User specific more info URL string.
  2581.  *
  2582.  */
  2583. STDMETHODIMP
  2584. HXClientEngine::Report
  2585. (
  2586.     const UINT8 unSeverity,
  2587.     HX_RESULT   ulHXCode,
  2588.     const ULONG32       ulUserCode,
  2589.     const char* pUserString,
  2590.     const char* pMoreInfoURL
  2591. )
  2592. {
  2593.     if (m_PlayerList.GetCount())
  2594.     {
  2595.     HXPlayer* pHXPlayer = (HXPlayer*)m_PlayerList.GetTail();
  2596.     pHXPlayer->Report(unSeverity,
  2597.                ulHXCode,
  2598.                ulUserCode,
  2599.                pUserString,
  2600.                pMoreInfoURL);
  2601.     return HXR_OK;
  2602.     }
  2603.     return HXR_NOTIMPL;
  2604. }
  2605. /************************************************************************
  2606.  *  Method:
  2607.  *      IHXErrorMessages::GetErrorText
  2608.  *  Purpose:
  2609.  *      Call this method to get the text description of a RMA error code.
  2610.  *  Parameters:
  2611.  *      HX_RESULT ulHXCode (A RMA error code)
  2612.  *  Return Value:
  2613.  *      IHXBuffer* containing error text.
  2614.  */
  2615. STDMETHODIMP_ (IHXBuffer*)
  2616. HXClientEngine::GetErrorText(HX_RESULT ulHXCode)
  2617. {
  2618. #if defined(HELIX_FEATURE_RESOURCEMGR)
  2619.     if (!m_bInitialized)
  2620.     {
  2621.         _Initialize();
  2622.     }
  2623.     return GetResMgr()->GetErrorString(ulHXCode);
  2624. #else
  2625.     return NULL;
  2626. #endif /* HELIX_FEATURE_RESOURCEMGR */
  2627. }
  2628. /************************************************************************
  2629.  *  Method:
  2630.  *      HXClientEngine::StopAudioPlayback
  2631.  *  Purpose:
  2632.  *      Stop all players in this process if we use audio.
  2633.  *
  2634.  */
  2635. STDMETHODIMP
  2636. HXClientEngine::StopAudioPlayback(THIS)
  2637. {
  2638.     BOOL bAudio = FALSE;
  2639.     // First look for audio
  2640.     CHXSimpleList::Iterator ndxPlayer = m_PlayerList.Begin();
  2641.     for (; !bAudio && ndxPlayer != m_PlayerList.End(); ++ndxPlayer)
  2642.     {
  2643.     HXPlayer* pHXPlayer = (HXPlayer*) (*ndxPlayer);
  2644.     IUnknown* pUnk;
  2645.     HX_ASSERT(pHXPlayer);
  2646.     if (pHXPlayer->QueryInterface(IID_IHXAudioPlayer, (void**)&pUnk) == HXR_OK)
  2647.     {
  2648.         HX_ASSERT(pUnk);
  2649.         bAudio = ((IHXAudioPlayer*)pUnk)->GetAudioStreamCount() > 0;
  2650.         pUnk->Release();
  2651.     }
  2652.     }
  2653.     // If we use audio, stop all the players.
  2654.     if (bAudio)
  2655.     {
  2656.     ndxPlayer = m_PlayerList.Begin();
  2657.     for (; ndxPlayer != m_PlayerList.End(); ++ndxPlayer)
  2658.     {
  2659.         HXPlayer* pHXPlayer = (HXPlayer*) (*ndxPlayer);
  2660.         pHXPlayer->Stop();
  2661.     }
  2662.     }
  2663.     return HXR_OK;
  2664. }
  2665. void    
  2666. HXClientEngine::NotifyPlayState(BOOL bInPlayingState)
  2667. {
  2668.     if (m_pScheduler)
  2669.     {
  2670.     m_pScheduler->NotifyPlayState(bInPlayingState);
  2671.     }
  2672. }
  2673. //initialize the user's path, and store it in the registry
  2674. void
  2675. HXClientEngine::InitPaths()
  2676. {
  2677. #if !defined(__TCS__)
  2678.     BOOL bShouldUseDocsAndSettingsPath = FALSE;
  2679. #ifdef _WIN32
  2680.     HXVERSIONINFO pnvi;
  2681.     
  2682.     ::memset(&pnvi, 0, sizeof(pnvi));
  2683.     HXGetWinVer(&pnvi);
  2684.     if(pnvi.dwPlatformId == HX_PLATFORM_WINNT)
  2685.     {
  2686.         //this will be for win2k, nt, and XP
  2687.         bShouldUseDocsAndSettingsPath = TRUE;
  2688.     }
  2689. #endif
  2690. #if defined(_CARBON) || defined(_MAC_UNIX)
  2691.     bShouldUseDocsAndSettingsPath = TRUE;
  2692. #endif
  2693.     IHXBuffer* pBuffer = NULL;
  2694.     CHXString strUserDataPath;
  2695. #if defined(_CARBON) || defined(_MAC_UNIX)
  2696.     if (1) // on the Mac we'll always determine this at runtime since paths are not stable between runs
  2697. #else
  2698.         if (!m_pPreferences ||
  2699.     m_pPreferences->ReadPref("UserSDKDataPath", pBuffer) != HXR_OK)
  2700. #endif
  2701.         {
  2702.             BOOL bCreated = FALSE;
  2703.             // see if RealPlayer App Data Path is set and derive SDK path
  2704.             // from that
  2705.             if (bShouldUseDocsAndSettingsPath && m_pPreferences &&
  2706.                 m_pPreferences->ReadPref("UserDataPath", pBuffer) == HXR_OK)
  2707.             {
  2708.                 char* pDataPath = (char*) pBuffer->GetBuffer();
  2709.                 char* pRealPlayerStart = ::strstr(pDataPath, "RealPlayer");
  2710.                 if (pRealPlayerStart)
  2711.                 {
  2712.                     char* pTemp = new_string(pDataPath);
  2713.                     pTemp[pRealPlayerStart-pDataPath] = '';
  2714.                     strUserDataPath = pTemp;
  2715.                     delete [] pTemp;
  2716.                     strUserDataPath += HXVER_SDK_PRODUCT;
  2717.                     strUserDataPath += OS_SEPARATOR_STRING;
  2718.                     bCreated = TRUE;
  2719.                 }
  2720.                 HX_RELEASE(pBuffer);
  2721.             }
  2722.     
  2723.             if (!bCreated)
  2724.             {
  2725.                 if (bShouldUseDocsAndSettingsPath)
  2726.                 {
  2727. #if defined _WIN32 || defined _CARBON || defined _MAC_UNIX
  2728.                     // Do this for Win 2K, XP, and Mac OS X
  2729.                     CHXDirSpecifier dirBase = CHXFileSpecUtils::GetAppDataDir(HXVER_SDK_PRODUCT);
  2730.                     strUserDataPath = dirBase.GetPathName();
  2731.                     if(strUserDataPath[strUserDataPath.GetLength() - 1] != OS_SEPARATOR_CHAR)
  2732.                     {
  2733.                         strUserDataPath += OS_SEPARATOR_STRING;
  2734.                     }
  2735. #endif
  2736.                 }
  2737.                 else
  2738.                 {
  2739. #ifdef _UNIX
  2740.                     strUserDataPath = (const char*) getenv("HOME");
  2741.                     strUserDataPath += OS_SEPARATOR_CHAR;
  2742.                     strUserDataPath += ".helix";
  2743.                     strUserDataPath += OS_SEPARATOR_CHAR;
  2744. #else
  2745.                     strUserDataPath = (const char*) GetDLLAccessPath()->GetPath(DLLTYPE_COMMON);
  2746. #endif        
  2747.                 }
  2748.                 // need to create our own
  2749.             }
  2750.             pBuffer = new CHXBuffer();
  2751.             pBuffer->AddRef();
  2752.     
  2753.             pBuffer->Set((const unsigned char*)(const char*) strUserDataPath, strlen((const char*) strUserDataPath) + 1);
  2754.     if (m_pPreferences)
  2755.     {
  2756. m_pPreferences->WritePref("UserSDKDataPath", pBuffer);
  2757.     }
  2758.         }
  2759.         else
  2760.         {
  2761.             strUserDataPath = pBuffer->GetBuffer();
  2762.         }
  2763. #ifdef _WIN32
  2764.     DirCreatePath(strUserDataPath);
  2765. #endif
  2766.     HX_RELEASE(pBuffer);
  2767. #endif /* __TCS__ */
  2768. }
  2769. /************************************************************************
  2770.  *  Method:
  2771.  *      IHXCoreMutex::LockCoreMutex
  2772.  *  Purpose:
  2773.  *      Call this method to lock the client engine's core mutex.
  2774.  */
  2775. STDMETHODIMP
  2776. HXClientEngine::LockCoreMutex(THIS)
  2777. {
  2778.     HX_RESULT retval = HXR_FAIL;
  2779.     if (m_pCoreMutex)
  2780.     {
  2781.     retval = HXR_OK;
  2782.     m_pCoreMutex->Lock();
  2783.     }
  2784.     return retval;
  2785. }
  2786. /************************************************************************
  2787.  *  Method:
  2788.  *      IHXCoreMutex::UnlockCoreMutex
  2789.  *  Purpose:
  2790.  *      Call this method to unlock the client engine's core mutex.
  2791.  */
  2792. STDMETHODIMP
  2793. HXClientEngine::UnlockCoreMutex(THIS)
  2794. {
  2795.     HX_RESULT retval = HXR_FAIL;
  2796.     if (m_pCoreMutex)
  2797.     {
  2798.     retval = HXR_OK;
  2799.     m_pCoreMutex->Unlock();
  2800.     }
  2801.     return retval;
  2802. }
  2803. #if defined(_MACINTOSH) && defined(_CARBON) && defined(THREADS_SUPPORTED)
  2804. /************************************************************************
  2805.  *  Method:
  2806.  *      IHXMacBlitMutex::LockMacBlitMutex
  2807.  *  Purpose:
  2808.  *      Call this method to lock the Mac blitting mutex
  2809.  */
  2810. STDMETHODIMP
  2811. HXClientEngine::LockMacBlitMutex(THIS)
  2812. {
  2813.     HX_RESULT retval = HXR_FAIL;
  2814.     if (m_pMacBlitMutex)
  2815.     {
  2816. retval = HXR_OK;
  2817. if (m_bUseMacBlitMutex) m_pMacBlitMutex->Lock();
  2818.     }
  2819.     return retval;
  2820. }
  2821. /************************************************************************
  2822.  *  Method:
  2823.  *      IHXMacBlitMutex::UnlockMacBlitMutex
  2824.  *  Purpose:
  2825.  *      Call this method to unlock the Mac blitting mutex
  2826.  */
  2827. STDMETHODIMP
  2828. HXClientEngine::UnlockMacBlitMutex(THIS)
  2829. {
  2830.     HX_RESULT retval = HXR_FAIL;
  2831.     if (m_pMacBlitMutex)
  2832.     {
  2833. retval = HXR_OK;
  2834. if (m_bUseMacBlitMutex) m_pMacBlitMutex->Unlock();
  2835.     }
  2836.     return retval;
  2837. }
  2838. #endif