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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: thrhypnv.cpp,v 1.4.20.1 2004/07/09 02:05:46 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 <stdio.h>
  50. #include "hxtypes.h"
  51. #include "hxresult.h"
  52. #include "hxcom.h"
  53. #include "hxprefs.h"
  54. #include "hxhyper.h"
  55. #include "hxtick.h"
  56. #include "hxslist.h"
  57. #include "hxthread.h"
  58. #include "hxhypnv.h"
  59. #include "thrhypnv.h"
  60. #include "hxheap.h"
  61. #ifdef _DEBUG
  62. #undef HX_THIS_FILE
  63. static const char HX_THIS_FILE[] = __FILE__;
  64. #endif
  65. enum
  66. {
  67.      REINIT = 0
  68.     ,ONURL
  69. };
  70. void* HyperThreadRoutine(void * pArg);
  71. #ifdef _WIN32
  72. #define HXMSG_QUIT (WM_USER + 1000) /* Exit from the thread */
  73. #define HXURL_COMMAND (WM_USER + 1001) /* URL Command */
  74. #else
  75. #define HXMSG_QUIT 1000      /* Exit from the thread */
  76. #define HXURL_COMMAND 1001 /* URL Command */
  77. #endif /*_WIN32*/
  78. /****************************************************************************
  79.  *
  80.  *  Interface:
  81.  *
  82.  * HXHyperNavigate
  83.  *
  84.  *  Purpose:
  85.  *
  86.  * TBD
  87.  *
  88.  *  IID_IHXHyperNavigate:
  89.  *
  90.  * {00000900-61DF-11d0-9CEE-080017035B43}
  91.  *
  92.  */
  93. HXThreadHyperNavigate::HXThreadHyperNavigate() :
  94.       m_lRefCount(0)
  95.     , m_pContext(0)
  96.     , m_bInitialized(FALSE)
  97.     , m_pThread(NULL)
  98.     , m_pQuitEvent(NULL)
  99.     , m_bUseThread(FALSE)
  100.     , m_pHyperNavigate(NULL)
  101. {
  102. }
  103. HXThreadHyperNavigate::~HXThreadHyperNavigate()
  104. {
  105.     Stop();
  106. }
  107. /////////////////////////////////////////////////////////////////////////
  108. // Method:
  109. // IUnknown::QueryInterface
  110. // Purpose:
  111. // Implement this to export the interfaces supported by your
  112. // object.
  113. //
  114. STDMETHODIMP HXThreadHyperNavigate::QueryInterface(REFIID riid, void** ppvObj)
  115. {
  116.     QInterfaceList qiList[] =
  117.         {
  118.             { GET_IIDHANDLE(IID_IHXHyperNavigate), (IHXHyperNavigate*)this },
  119.             { GET_IIDHANDLE(IID_IHXHyperNavigate2), (IHXHyperNavigate2*)this },
  120.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXHyperNavigate*)this },
  121.         };
  122.     
  123.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  124. }
  125. /////////////////////////////////////////////////////////////////////////
  126. // Method:
  127. // IUnknown::AddRef
  128. // Purpose:
  129. // Everyone usually implements this the same... feel free to use
  130. // this implementation.
  131. //
  132. STDMETHODIMP_(ULONG32) HXThreadHyperNavigate::AddRef()
  133. {
  134.     return InterlockedIncrement(&m_lRefCount);
  135. }
  136. /////////////////////////////////////////////////////////////////////////
  137. // Method:
  138. // IUnknown::Release
  139. // Purpose:
  140. // Everyone usually implements this the same... feel free to use
  141. // this implementation.
  142. //
  143. STDMETHODIMP_(ULONG32) HXThreadHyperNavigate::Release()
  144. {
  145.     if (InterlockedDecrement(&m_lRefCount) > 0)
  146.     {
  147. return m_lRefCount;
  148.     }
  149.     delete this;
  150.     return 0;
  151. }
  152. STDMETHODIMP HXThreadHyperNavigate::Init(IUnknown* pContext)
  153. {
  154.     if (!pContext)
  155.     {
  156. return HXR_UNEXPECTED;
  157.     }
  158.     HX_RESULT theErr = HXR_OK;
  159.     HX_RELEASE(m_pContext);
  160.     m_pContext = pContext;
  161.     m_pContext->AddRef();
  162.     if (!m_bUseThread)
  163.     {
  164. if (!m_pHyperNavigate)
  165. {
  166.     m_pHyperNavigate = new HXHyperNavigate;
  167.     m_pHyperNavigate->AddRef();
  168. }
  169. theErr = m_pHyperNavigate->Init(m_pContext);
  170.     }
  171.     else
  172.     {
  173. StartHyperThread();
  174. HyperCommand* pCommand = new HyperCommand;
  175. pCommand->m_Type = REINIT;
  176. HXThreadMessage msg(HXURL_COMMAND, (void*) pCommand, NULL);
  177. m_pThread->PostMessage(&msg);
  178.     }
  179.     m_bInitialized = TRUE;
  180.     return theErr;
  181. }
  182. void     
  183. HXThreadHyperNavigate::UseThread(BOOL bUseThread)
  184. {
  185. #ifdef THREADS_SUPPORTED
  186.     m_bUseThread = bUseThread;
  187.     if (!m_bInitialized)
  188.     {
  189. return;
  190.     }
  191.     if (m_bUseThread)
  192.     {
  193. if (!m_pThread)
  194. {
  195.     HX_RELEASE(m_pHyperNavigate);
  196.     StartHyperThread();
  197.     /* Reinitialize*/
  198.     Init(m_pContext);
  199. }
  200.     }
  201.     else
  202.     {
  203. if (m_pThread)
  204. {
  205.     StopHyperThread();
  206.     HX_ASSERT(m_pHyperNavigate == NULL);
  207.     /* Reinitialize*/
  208.     Init(m_pContext);
  209. }
  210.     }
  211. #endif /*THREADS_SUPPORTED*/
  212. }
  213. void     
  214. HXThreadHyperNavigate::Stop(void)
  215. {
  216.     StopHyperThread();
  217.     HX_RELEASE(m_pContext);
  218.     HX_RELEASE(m_pHyperNavigate);
  219. }
  220. /*
  221.  * IHXHyperNavigate methods
  222.  */
  223. /************************************************************************
  224.  * Method:
  225.  *     IHXHyperNavigate::GoToURL
  226.  * Purpose:
  227.  *     Performs a simple Go To URL operation.
  228.  */
  229. STDMETHODIMP HXThreadHyperNavigate::GoToURL( const char* pURL,
  230. const char* pTarget)
  231. {
  232.     if (!pURL)
  233.     {
  234. return HXR_UNEXPECTED;
  235.     }
  236.     if (!m_bUseThread)
  237.     {
  238. return m_pHyperNavigate->GoToURL(pURL, pTarget);
  239.     }
  240.     else
  241.     {
  242. HyperCommand* pCommand = new HyperCommand;
  243. pCommand->m_Type = ONURL;
  244. pCommand->m_pURL = new char[strlen(pURL) + 1];
  245. strcpy(pCommand->m_pURL, pURL); /* Flawfinder: ignore */
  246. if (pTarget)
  247. {
  248.     pCommand->m_pTarget = new char[strlen(pTarget) + 1];
  249.     strcpy(pCommand->m_pTarget, pTarget); /* Flawfinder: ignore */
  250. }
  251. HXThreadMessage msg(HXURL_COMMAND, (void*) pCommand, NULL);
  252. m_pThread->PostMessage(&msg);
  253. return HXR_OK;
  254.     }
  255. }
  256. /************************************************************************
  257.  * Method:
  258.  *     IHXHyperNavigate2::Execute
  259.  * Purpose:
  260.  *     
  261.  * Parameters:
  262.  *      pURL:     URL (absolute or relative)
  263.  *     pTargetInstance:
  264.  *     pTargetApplication: 
  265.  *     pTargetRegion:
  266.  *     pParams:
  267.  */
  268. STDMETHODIMP 
  269. HXThreadHyperNavigate::Execute(const char* pURL,
  270.   const char* pTargetInstance,
  271.   const char* pTargetApplication,
  272.   const char* pTargetRegion,
  273.   IHXValues* pParams)
  274. {
  275.     return GoToURL(pURL, pTargetInstance);
  276. }
  277. void
  278. HXThreadHyperNavigate::StartHyperThread()
  279. {
  280.     if (m_pThread)
  281.     {
  282. return;
  283.     }
  284.     HX_RELEASE(m_pHyperNavigate);
  285. #ifdef THREADS_SUPPORTED
  286.     HXThread::MakeThread(m_pThread);
  287.     HXEvent::MakeEvent(m_pQuitEvent, NULL);
  288. #else
  289.     HXThread::MakeStubThread(m_pThread);
  290.     HXEvent::MakeStubEvent(m_pQuitEvent, NULL);
  291. #endif
  292.     m_pThread->CreateThread(HyperThreadRoutine, (void*) this);
  293. }
  294. void HXThreadHyperNavigate::StopHyperThread()
  295. {
  296.     if (m_pThread)
  297.     {
  298. HXThreadMessage msg(HXMSG_QUIT, NULL, NULL);
  299. if (m_pThread->PostMessage(&msg) == HXR_OK)
  300. {
  301.     m_pQuitEvent->Wait(ALLFS);
  302. }
  303. #ifdef _MACINTOSH /* @@@CXZ - ALLFS sometimes causes browsers to hang when quitting embedded player */
  304. m_pQuitEvent->Wait(500);
  305. #else
  306. m_pQuitEvent->Wait(ALLFS);
  307. #endif
  308. m_pThread->Exit(0);
  309. delete m_pThread;
  310. m_pThread = 0;
  311.     }
  312.     HX_DELETE(m_pQuitEvent);
  313. }
  314. void*
  315. HyperThreadRoutine(void * pArg)
  316. {
  317.     HXThreadHyperNavigate* pThreadHyperNavigate = 
  318.     (HXThreadHyperNavigate*) pArg;
  319.     HXThread*     pThread = pThreadHyperNavigate->m_pThread;
  320.     HyperCommand*   pCommand = NULL;
  321.     BOOL     bDone = FALSE;
  322.     HXThreadMessage msg;
  323.     if (!pThreadHyperNavigate->m_pHyperNavigate)
  324.     {
  325. pThreadHyperNavigate->m_pHyperNavigate = new HXHyperNavigate;
  326. pThreadHyperNavigate->m_pHyperNavigate->AddRef();
  327.     }
  328.     HXHyperNavigate* pHyperNavigate = 
  329. pThreadHyperNavigate->m_pHyperNavigate;
  330.     while (!bDone && pThread->GetMessage(&msg, 0,0) == HXR_OK)
  331.     {
  332. switch (msg.m_ulMessage)
  333. {
  334.     case HXURL_COMMAND:
  335. {
  336.     pCommand = (HyperCommand*) msg.m_pParam1; 
  337.     switch (pCommand->m_Type)
  338.     {
  339. case REINIT:
  340.     pHyperNavigate->Init(pThreadHyperNavigate->m_pContext);
  341.     break;
  342. case ONURL:
  343.     pHyperNavigate->GoToURL(pCommand->m_pURL, 
  344.     pCommand->m_pTarget);
  345.     break;
  346. default:
  347.     HX_ASSERT(FALSE);
  348.     break;
  349.     }
  350.     delete pCommand;
  351. }
  352. break;
  353.     case HXMSG_QUIT:
  354. bDone = TRUE;
  355. break;
  356.     default:
  357. pThread->DispatchMessage(&msg);
  358. break;
  359. }
  360.     }
  361.     HX_RELEASE(pThreadHyperNavigate->m_pHyperNavigate);
  362.     pThreadHyperNavigate->m_pQuitEvent->SignalEvent();
  363.     return (void*) 0;
  364. }