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

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include <stdio.h>
  36. #include "hxtypes.h"
  37. #include "hxresult.h"
  38. #include "hxcom.h"
  39. #include "hxprefs.h"
  40. #include "hxhyper.h"
  41. #include "hxtick.h"
  42. #include "hxslist.h"
  43. #include "hxthread.h"
  44. #include "hxhypnv.h"
  45. #include "thrhypnv.h"
  46. #include "hxheap.h"
  47. #ifdef _DEBUG
  48. #undef HX_THIS_FILE
  49. static const char HX_THIS_FILE[] = __FILE__;
  50. #endif
  51. enum
  52. {
  53.      REINIT = 0
  54.     ,ONURL
  55. };
  56. void* HyperThreadRoutine(void * pArg);
  57. #ifdef _WIN32
  58. #define HXMSG_QUIT (WM_USER + 1000) /* Exit from the thread */
  59. #define HXURL_COMMAND (WM_USER + 1001) /* URL Command */
  60. #else
  61. #define HXMSG_QUIT 1000      /* Exit from the thread */
  62. #define HXURL_COMMAND 1001 /* URL Command */
  63. #endif /*_WIN32*/
  64. /****************************************************************************
  65.  *
  66.  *  Interface:
  67.  *
  68.  * HXHyperNavigate
  69.  *
  70.  *  Purpose:
  71.  *
  72.  * TBD
  73.  *
  74.  *  IID_IHXHyperNavigate:
  75.  *
  76.  * {00000900-61DF-11d0-9CEE-080017035B43}
  77.  *
  78.  */
  79. HXThreadHyperNavigate::HXThreadHyperNavigate() :
  80.       m_lRefCount(0)
  81.     , m_pContext(0)
  82.     , m_bInitialized(FALSE)
  83.     , m_pThread(NULL)
  84.     , m_pQuitEvent(NULL)
  85.     , m_bUseThread(FALSE)
  86.     , m_pHyperNavigate(NULL)
  87. {
  88. }
  89. HXThreadHyperNavigate::~HXThreadHyperNavigate()
  90. {
  91.     Stop();
  92. }
  93. /////////////////////////////////////////////////////////////////////////
  94. // Method:
  95. // IUnknown::QueryInterface
  96. // Purpose:
  97. // Implement this to export the interfaces supported by your
  98. // object.
  99. //
  100. STDMETHODIMP HXThreadHyperNavigate::QueryInterface(REFIID riid, void** ppvObj)
  101. {
  102.     QInterfaceList qiList[] =
  103.         {
  104.             { GET_IIDHANDLE(IID_IHXHyperNavigate), (IHXHyperNavigate*)this },
  105.             { GET_IIDHANDLE(IID_IHXHyperNavigate2), (IHXHyperNavigate2*)this },
  106.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXHyperNavigate*)this },
  107.         };
  108.     
  109.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  110. }
  111. /////////////////////////////////////////////////////////////////////////
  112. // Method:
  113. // IUnknown::AddRef
  114. // Purpose:
  115. // Everyone usually implements this the same... feel free to use
  116. // this implementation.
  117. //
  118. STDMETHODIMP_(ULONG32) HXThreadHyperNavigate::AddRef()
  119. {
  120.     return InterlockedIncrement(&m_lRefCount);
  121. }
  122. /////////////////////////////////////////////////////////////////////////
  123. // Method:
  124. // IUnknown::Release
  125. // Purpose:
  126. // Everyone usually implements this the same... feel free to use
  127. // this implementation.
  128. //
  129. STDMETHODIMP_(ULONG32) HXThreadHyperNavigate::Release()
  130. {
  131.     if (InterlockedDecrement(&m_lRefCount) > 0)
  132.     {
  133. return m_lRefCount;
  134.     }
  135.     delete this;
  136.     return 0;
  137. }
  138. STDMETHODIMP HXThreadHyperNavigate::Init(IUnknown* pContext)
  139. {
  140.     if (!pContext)
  141.     {
  142. return HXR_UNEXPECTED;
  143.     }
  144.     HX_RESULT theErr = HXR_OK;
  145.     HX_RELEASE(m_pContext);
  146.     m_pContext = pContext;
  147.     m_pContext->AddRef();
  148.     if (!m_bUseThread)
  149.     {
  150. if (!m_pHyperNavigate)
  151. {
  152.     m_pHyperNavigate = new HXHyperNavigate;
  153.     m_pHyperNavigate->AddRef();
  154. }
  155. theErr = m_pHyperNavigate->Init(m_pContext);
  156.     }
  157.     else
  158.     {
  159. StartHyperThread();
  160. HyperCommand* pCommand = new HyperCommand;
  161. pCommand->m_Type = REINIT;
  162. HXThreadMessage msg(HXURL_COMMAND, (void*) pCommand, NULL);
  163. m_pThread->PostMessage(&msg);
  164.     }
  165.     m_bInitialized = TRUE;
  166.     return theErr;
  167. }
  168. void     
  169. HXThreadHyperNavigate::UseThread(BOOL bUseThread)
  170. {
  171. #ifdef THREADS_SUPPORTED
  172.     m_bUseThread = bUseThread;
  173.     if (!m_bInitialized)
  174.     {
  175. return;
  176.     }
  177.     if (m_bUseThread)
  178.     {
  179. if (!m_pThread)
  180. {
  181.     HX_RELEASE(m_pHyperNavigate);
  182.     StartHyperThread();
  183.     /* Reinitialize*/
  184.     Init(m_pContext);
  185. }
  186.     }
  187.     else
  188.     {
  189. if (m_pThread)
  190. {
  191.     StopHyperThread();
  192.     HX_ASSERT(m_pHyperNavigate == NULL);
  193.     /* Reinitialize*/
  194.     Init(m_pContext);
  195. }
  196.     }
  197. #endif /*THREADS_SUPPORTED*/
  198. }
  199. void     
  200. HXThreadHyperNavigate::Stop(void)
  201. {
  202.     StopHyperThread();
  203.     HX_RELEASE(m_pContext);
  204.     HX_RELEASE(m_pHyperNavigate);
  205. }
  206. /*
  207.  * IHXHyperNavigate methods
  208.  */
  209. /************************************************************************
  210.  * Method:
  211.  *     IHXHyperNavigate::GoToURL
  212.  * Purpose:
  213.  *     Performs a simple Go To URL operation.
  214.  */
  215. STDMETHODIMP HXThreadHyperNavigate::GoToURL( const char* pURL,
  216. const char* pTarget)
  217. {
  218.     if (!pURL)
  219.     {
  220. return HXR_UNEXPECTED;
  221.     }
  222.     if (!m_bUseThread)
  223.     {
  224. return m_pHyperNavigate->GoToURL(pURL, pTarget);
  225.     }
  226.     else
  227.     {
  228. HyperCommand* pCommand = new HyperCommand;
  229. pCommand->m_Type = ONURL;
  230. pCommand->m_pURL = new char[strlen(pURL) + 1];
  231. strcpy(pCommand->m_pURL, pURL); /* Flawfinder: ignore */
  232. if (pTarget)
  233. {
  234.     pCommand->m_pTarget = new char[strlen(pTarget) + 1];
  235.     strcpy(pCommand->m_pTarget, pTarget); /* Flawfinder: ignore */
  236. }
  237. HXThreadMessage msg(HXURL_COMMAND, (void*) pCommand, NULL);
  238. m_pThread->PostMessage(&msg);
  239. return HXR_OK;
  240.     }
  241. }
  242. /************************************************************************
  243.  * Method:
  244.  *     IHXHyperNavigate2::Execute
  245.  * Purpose:
  246.  *     
  247.  * Parameters:
  248.  *      pURL:     URL (absolute or relative)
  249.  *     pTargetInstance:
  250.  *     pTargetApplication: 
  251.  *     pTargetRegion:
  252.  *     pParams:
  253.  */
  254. STDMETHODIMP 
  255. HXThreadHyperNavigate::Execute(const char* pURL,
  256.   const char* pTargetInstance,
  257.   const char* pTargetApplication,
  258.   const char* pTargetRegion,
  259.   IHXValues* pParams)
  260. {
  261.     return GoToURL(pURL, pTargetInstance);
  262. }
  263. void
  264. HXThreadHyperNavigate::StartHyperThread()
  265. {
  266.     if (m_pThread)
  267.     {
  268. return;
  269.     }
  270.     HX_RELEASE(m_pHyperNavigate);
  271. #ifdef THREADS_SUPPORTED
  272.     HXThread::MakeThread(m_pThread);
  273.     HXEvent::MakeEvent(m_pQuitEvent, NULL);
  274. #else
  275.     HXThread::MakeStubThread(m_pThread);
  276.     HXEvent::MakeStubEvent(m_pQuitEvent, NULL);
  277. #endif
  278.     m_pThread->CreateThread(HyperThreadRoutine, (void*) this);
  279. }
  280. void HXThreadHyperNavigate::StopHyperThread()
  281. {
  282.     if (m_pThread)
  283.     {
  284. HXThreadMessage msg(HXMSG_QUIT, NULL, NULL);
  285. if (m_pThread->PostMessage(&msg) == HXR_OK)
  286. {
  287.     m_pQuitEvent->Wait(ALLFS);
  288. }
  289. #ifdef _MACINTOSH /* @@@CXZ - ALLFS sometimes causes browsers to hang when quitting embedded player */
  290. m_pQuitEvent->Wait(500);
  291. #else
  292. m_pQuitEvent->Wait(ALLFS);
  293. #endif
  294. m_pThread->Exit(0);
  295. delete m_pThread;
  296. m_pThread = 0;
  297.     }
  298.     HX_DELETE(m_pQuitEvent);
  299. }
  300. void*
  301. HyperThreadRoutine(void * pArg)
  302. {
  303.     HXThreadHyperNavigate* pThreadHyperNavigate = 
  304.     (HXThreadHyperNavigate*) pArg;
  305.     HXThread*     pThread = pThreadHyperNavigate->m_pThread;
  306.     HyperCommand*   pCommand = NULL;
  307.     BOOL     bDone = FALSE;
  308.     HXThreadMessage msg;
  309.     if (!pThreadHyperNavigate->m_pHyperNavigate)
  310.     {
  311. pThreadHyperNavigate->m_pHyperNavigate = new HXHyperNavigate;
  312. pThreadHyperNavigate->m_pHyperNavigate->AddRef();
  313.     }
  314.     HXHyperNavigate* pHyperNavigate = 
  315. pThreadHyperNavigate->m_pHyperNavigate;
  316.     while (!bDone && pThread->GetMessage(&msg, 0,0) == HXR_OK)
  317.     {
  318. switch (msg.m_ulMessage)
  319. {
  320.     case HXURL_COMMAND:
  321. {
  322.     pCommand = (HyperCommand*) msg.m_pParam1; 
  323.     switch (pCommand->m_Type)
  324.     {
  325. case REINIT:
  326.     pHyperNavigate->Init(pThreadHyperNavigate->m_pContext);
  327.     break;
  328. case ONURL:
  329.     pHyperNavigate->GoToURL(pCommand->m_pURL, 
  330.     pCommand->m_pTarget);
  331.     break;
  332. default:
  333.     HX_ASSERT(FALSE);
  334.     break;
  335.     }
  336.     delete pCommand;
  337. }
  338. break;
  339.     case HXMSG_QUIT:
  340. bDone = TRUE;
  341. break;
  342.     default:
  343. pThread->DispatchMessage(&msg);
  344. break;
  345. }
  346.     }
  347.     HX_RELEASE(pThreadHyperNavigate->m_pHyperNavigate);
  348.     pThreadHyperNavigate->m_pQuitEvent->SignalEvent();
  349.     return (void*) 0;
  350. }