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

Symbian

开发平台:

Visual C++

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