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

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
  36. #include "hxtypes.h"
  37. #include "hxwintyp.h"
  38. #include "hxcom.h"
  39. #include "hxassert.h"
  40. #ifdef _WINDOWS
  41. #include <windows.h>
  42. #include "resource.h"
  43. #elif defined(_UNIX) && defined(USE_XWINDOWS)
  44. #include <X11/cursorfont.h>
  45. #include <X11/Intrinsic.h>
  46. #elif defined(_MACINTOSH) || defined(_MAC_UNIX)
  47. #include <ctype.h>
  48. #include "platform/mac/cresload.h"
  49. extern FSSpec g_DLLFSpec;
  50. //CResourceLoader* CResourceLoader::zm_theResourceLoader = NULL;
  51. #endif
  52. #include "hxcomm.h"
  53. #include "ihxpckts.h"
  54. #include "hxhyper.h"
  55. #include "hxupgrd.h"
  56. #include "hxprefs.h"
  57. #include "hxplugn.h"
  58. #include "hxengin.h"
  59. #include "hxrendr.h"
  60. #include "hxwin.h"
  61. #include "hxmon.h"
  62. #include "hxcore.h"
  63. #include "hxasm.h"
  64. #include "hxvsurf.h"
  65. #include "hxevent.h"
  66. #include "hxerror.h"
  67. // pncont
  68. #include "hxbuffer.h"
  69. // pnmisc
  70. #include "unkimp.h"
  71. #include "baseobj.h"
  72. // baserend
  73. #include "baserend.h"
  74. #include "vbasernd.h"
  75. #ifdef _WINDOWS
  76. extern HINSTANCE g_hInstance;
  77. #endif
  78. CRNVisualBaseRenderer::CRNVisualBaseRenderer()
  79.     : CRNBaseRenderer()
  80. {
  81.     m_cWindowSize.cx        = 0;
  82.     m_cWindowSize.cy        = 0;
  83.     m_pMISUS                = NULL;
  84.     m_pSite                 = NULL;
  85.     m_pStatusMessage        = NULL;
  86.     m_sOldMouseX            = -1;
  87.     m_sOldMouseY            = -1;
  88.     m_bStatusMsgWillNeedErasing = FALSE;
  89.     m_bSetHyperlinkCursor   = FALSE;
  90. #if defined(_WINDOWS)
  91.     m_hPreHyperlinkCursor   = NULL;
  92.     m_hHyperlinkCursor      = NULL;
  93. #elif defined(_MACINTOSH)
  94.     const short HAND_CURSOR = 1313;
  95.     m_eCurrentCursor        = CURSOR_ARROW;
  96.     m_pResourceLoader = CResourceLoader::CreateInstance(g_DLLFSpec);
  97.     m_hHyperlinkCursor = (CursHandle)m_pResourceLoader->LoadResource('CURS', HAND_CURSOR);
  98. #elif defined(_UNIX) && defined(USE_XWINDOWS)
  99.     m_pDisplay             = 0;
  100.     m_Window               = 0;
  101.     m_hHyperlinkCursor     = 0;
  102.     m_hCurrentCursor       = 0;
  103. #endif
  104. }
  105. CRNVisualBaseRenderer::~CRNVisualBaseRenderer()
  106. {
  107.     HX_RELEASE(m_pMISUS);
  108.     HX_RELEASE(m_pSite);
  109.     HX_RELEASE(m_pStatusMessage);
  110. #if defined(_MACINTOSH)
  111.     if (m_hHyperlinkCursor)
  112.     {
  113.      m_pResourceLoader->UnloadResource((Handle)m_hHyperlinkCursor);
  114.      m_hHyperlinkCursor = NULL;
  115.     
  116.      HX_RELEASE(m_pResourceLoader);
  117.     }
  118. #endif
  119. #if defined(_UNIX) && defined(USE_XWINDOWS)
  120.     if (m_pDisplay && m_hHyperlinkCursor)
  121.     {
  122. XFreeCursor(m_pDisplay, m_hHyperlinkCursor);
  123. m_hHyperlinkCursor = 0;
  124.     }
  125. #endif    
  126. }
  127. STDMETHODIMP CRNVisualBaseRenderer::QueryInterface(REFIID riid, void** ppvObj)
  128. {
  129.     HX_RESULT retVal = HXR_OK;
  130.     if (ppvObj)
  131.     {
  132.         // Set default
  133.         *ppvObj = NULL;
  134.         // Check for IID type
  135.         if (IsEqualIID(riid, IID_IHXSiteUser))
  136.         {
  137.             AddRef();
  138.             *ppvObj = (IHXSiteUser*) this;
  139.         }
  140.         else if (IsEqualIID(riid, IID_IHXSiteUserSupplier))
  141.         {
  142.             if (m_pMISUS)
  143.             {
  144.                 return m_pMISUS->QueryInterface(IID_IHXSiteUserSupplier, ppvObj);
  145.             }
  146.             else
  147.             {
  148.                 retVal = HXR_UNEXPECTED;
  149.             }
  150.         }
  151.         else
  152.         {
  153.             // If we don't support it, then QI our
  154.             // base class for this interface
  155.             retVal = CRNBaseRenderer::QueryInterface(riid, ppvObj);
  156.         }
  157.     }
  158.     else
  159.     {
  160.         retVal = HXR_FAIL;
  161.     }
  162.     return retVal;
  163. }
  164. STDMETHODIMP_(UINT32) CRNVisualBaseRenderer::AddRef()
  165. {
  166.     return CRNBaseRenderer::AddRef();
  167. }
  168. STDMETHODIMP_(UINT32) CRNVisualBaseRenderer::Release()
  169. {
  170.     return CRNBaseRenderer::Release();
  171. }
  172. STDMETHODIMP CRNVisualBaseRenderer::InitPlugin(IUnknown *pContext)
  173. {
  174.     HX_RESULT retVal = CRNBaseRenderer::InitPlugin(pContext);
  175.     if (SUCCEEDED(retVal))
  176.     {
  177.         // Now we need to get IHXStatusMessage - OK if TLC doesn't support it
  178.         HX_RELEASE(m_pStatusMessage);
  179.         pContext->QueryInterface(IID_IHXStatusMessage, (void**) &m_pStatusMessage);
  180.     }
  181.     return retVal;
  182. }
  183. STDMETHODIMP CRNVisualBaseRenderer::StartStream(IHXStream* pStream, IHXPlayer* pPlayer)
  184. {
  185.     HX_RESULT retVal   = HXR_OK;
  186.     // Call the super-class's StartStream()
  187.     retVal = CRNBaseRenderer::StartStream(pStream, pPlayer);
  188. #if defined (HELIX_FEATURE_MISU)
  189.     if (SUCCEEDED(retVal))
  190.     {
  191.         // Create a IHXMultiInstanceSiteUserSupplier interface
  192.         HX_RELEASE(m_pMISUS);
  193.         retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXMultiInstanceSiteUserSupplier,
  194.                                                        (void**) &m_pMISUS);
  195.         if (SUCCEEDED(retVal))
  196.         {
  197.             // Register ourselves as a site user
  198.             retVal = m_pMISUS->SetSingleSiteUser((IUnknown*) (IHXSiteUser*) this);
  199.         }
  200.     }
  201. #endif
  202.     // Clean up the state if there was an error
  203.     if (FAILED(retVal))
  204.     {
  205.         HX_RELEASE(m_pStream);
  206.         HX_RELEASE(m_pPlayer);
  207.         HX_RELEASE(m_pBackChannel);
  208.         HX_RELEASE(m_pASMStream);
  209.         HX_RELEASE(m_pMISUS);
  210.     }
  211.     return retVal;
  212. }
  213. STDMETHODIMP CRNVisualBaseRenderer::AttachSite(IHXSite *pSite)
  214. {
  215.     HX_RESULT retVal = HXR_OK;
  216.     if (pSite)
  217.     {
  218.         // Check to see if we alredy have a site interface
  219.         if (!m_pSite)
  220.         {
  221.             // Save a copy of the IHXSite interface
  222.             m_pSite = pSite;
  223.             m_pSite->AddRef();
  224.             // Get the window size from the sub-class
  225.             retVal = GetWindowSize(m_cWindowSize);
  226.             if (SUCCEEDED(retVal))
  227.             {
  228.                 // Inform the site of our size
  229.                 retVal = m_pSite->SetSize(m_cWindowSize);
  230.             }
  231.             //Give sub class a change to set up site.
  232.             _AttachSite();
  233.         }
  234.         else
  235.         {
  236.             retVal = HXR_UNEXPECTED;
  237.         }
  238.     }
  239.     else
  240.     {
  241.         retVal = HXR_FAIL;
  242.     }
  243.     if (FAILED(retVal))
  244.     {
  245.         HX_RELEASE(m_pSite);
  246.     }
  247.     return retVal;
  248. }
  249. STDMETHODIMP CRNVisualBaseRenderer::DetachSite()
  250. {
  251.     // Release our IHXSite interface
  252.     HX_RELEASE(m_pSite);
  253.     // Now we're done with the MISUS
  254.     if (m_pMISUS)
  255.     {
  256.         m_pMISUS->ReleaseSingleSiteUser();
  257.     }
  258.     HX_RELEASE(m_pMISUS);
  259.     return HXR_OK;
  260. }
  261. HX_RESULT CRNVisualBaseRenderer::RMASurfaceUpdate2(IHXSubRectVideoSurface* pSurface,
  262.                                                    HXxRect*                 pExtents,
  263.                                                    HXxBoxRegion*              pDirtyRegion)
  264. {
  265.     //Base impl. Should never be called except by those renderers that
  266.     //subscribe to the sub rect messages and implemnet this themselves.
  267.     HX_ASSERT( "Should Never be called."==NULL );
  268.     return HXR_OK;
  269. }
  270. STDMETHODIMP CRNVisualBaseRenderer::HandleEvent(HXxEvent *pEvent)
  271. {
  272.     // Check for input error
  273.     if (!pEvent)
  274.     {
  275.         return HXR_FAIL;
  276.     }
  277.     // Set the defaults
  278.     pEvent->handled = FALSE;
  279.     pEvent->result  = 0;
  280.     switch (pEvent->event)
  281.     {
  282.        case HX_SURFACE_UPDATE2:
  283.        {
  284.            
  285.            HXxExposeInfo* pExpose = (HXxExposeInfo*)pEvent->param2;
  286.            IHXSubRectVideoSurface *pSurface = (IHXSubRectVideoSurface*) (pEvent->param1);
  287.            if (pSurface)
  288.            {
  289.                pSurface->AddRef();
  290.                RMASurfaceUpdate2(pSurface, &pExpose->extents, pExpose->pRegion);
  291.                HX_RELEASE(pSurface);
  292.            }
  293.            pEvent->handled = TRUE;           
  294.        }
  295.        break;
  296.            
  297.        case HX_SURFACE_UPDATE:
  298.        {
  299.             IHXVideoSurface *pSurface = (IHXVideoSurface *) (pEvent->param1);
  300.             if (pSurface)
  301.             {
  302.                 pSurface->AddRef();
  303.                 RMASurfaceUpdate(pSurface);
  304.                 HX_RELEASE(pSurface);
  305.             }
  306. #if defined(_UNIX) && defined(USE_XWINDOWS)
  307.     //
  308.     // Create a "hand" cursor for hyperlinks
  309.     //
  310.     {
  311. //
  312. // free previously allocated cursor
  313. //
  314. if (m_pDisplay && m_hHyperlinkCursor)
  315. {
  316.     XFreeCursor(m_pDisplay, m_hHyperlinkCursor);
  317.     m_hHyperlinkCursor = 0;
  318. }
  319. // 
  320. // get new display/window parameters and 
  321. // allocate a new cursor
  322. //
  323. HXxWindow *pWnd = (HXxWindow*)pEvent->param2;
  324. m_pDisplay = (Display*)pWnd->display;
  325. m_Window = (Window)pWnd->window;
  326. if (m_pDisplay)
  327.     m_hHyperlinkCursor = XCreateFontCursor(m_pDisplay, XC_hand2);
  328.     }     
  329. #endif
  330.             pEvent->handled = TRUE;
  331.         }
  332.         break;
  333.         case HX_MOUSE_ENTER:
  334.         case HX_MOUSE_LEAVE:
  335.         case HX_MOUSE_MOVE:
  336.         {
  337.             HXxPoint* mousePt = (HXxPoint*) pEvent->param1;
  338.             OnMouseMove(0, (INT16) mousePt->x, (INT16) mousePt->y);
  339.             pEvent->handled = TRUE;
  340.         }
  341.         break;
  342.         case HX_PRIMARY_BUTTON_UP:
  343.         {
  344.             HXxPoint* mousePt = (HXxPoint*) pEvent->param1;
  345.             HandleClick((INT16) mousePt->x, (INT16) mousePt->y);
  346.             pEvent->handled = TRUE;
  347.         }
  348.         break;
  349. #ifdef _WINDOWS
  350.         case WM_SETCURSOR:
  351.         {
  352.             if(m_bSetHyperlinkCursor)
  353.             {
  354.                 pEvent->handled       = TRUE;
  355.                 m_hPreHyperlinkCursor = SetCursor(m_hHyperlinkCursor);
  356.             }
  357.             else
  358.             {
  359.                 // pngui will handle the setting of the cursor (back to arrow cursor)
  360.                 pEvent->handled       = FALSE;
  361.             }
  362.         }
  363.         break;
  364. #endif
  365.         default:
  366.             break;
  367.     }
  368.     return HXR_OK;
  369. }
  370. STDMETHODIMP_(BOOL) CRNVisualBaseRenderer::NeedsWindowedSites()
  371. {
  372.     return FALSE;
  373. }
  374. STDMETHODIMP CRNVisualBaseRenderer::OnMouseMove(INT16 fwKeys, INT16 xPos, INT16 yPos)
  375. {
  376.     // Make sure we're up and running
  377.     if (!m_pPlayer)
  378.     {
  379.         return HXR_OK;
  380.     }
  381.     // Don't do anything if the x/y coordinates have changed from the
  382.     // last call to OnMouseMove - this is needed because the call to
  383.     // IHXStatusMessage::SetStatus() results in a WM_MOUSEMOVE event
  384.     if(xPos == m_sOldMouseX && yPos == m_sOldMouseY)
  385.     {
  386.         return HXR_OK;
  387.     }
  388.     m_sOldMouseX = xPos;
  389.     m_sOldMouseY = yPos;
  390. #if defined(_WINDOWS)
  391.     HCURSOR hCurrentCursor = GetCursor();
  392. #endif
  393.     // Find out from the sub-class if we're over an active hyperlink
  394.     IHXBuffer* pStatusStr     = NULL;
  395.     BOOL        bOverHyperlink = FALSE;
  396.     HX_RESULT   retVal         = IsMouseOverActiveLink(xPos, yPos, bOverHyperlink, pStatusStr);
  397.     if (FAILED(retVal))
  398.     {
  399.         return retVal;
  400.     }
  401.     if (bOverHyperlink)
  402.     {
  403.         // Set the status bar
  404.         if (m_pStatusMessage)
  405.         {
  406.     m_bStatusMsgWillNeedErasing = TRUE;
  407.             m_pStatusMessage->SetStatus((const char*) pStatusStr->GetBuffer());
  408.         }
  409.         HX_RELEASE(pStatusStr);
  410.         // Set the cursor
  411. #if defined(_WINDOWS)
  412.         if(!m_hHyperlinkCursor)
  413.         {
  414.             m_hHyperlinkCursor = LoadCursor(g_hInstance, MAKEINTRESOURCE(HANDCURSOR));
  415.             if(!m_hHyperlinkCursor)
  416.             {
  417.                 m_hHyperlinkCursor = LoadCursor(NULL, IDC_UPARROW);
  418.             }
  419.         }
  420.         if(m_hHyperlinkCursor && hCurrentCursor != m_hHyperlinkCursor)
  421.         {
  422.             // We're over a link and the cursor is NOT already the hyperlink cursor,
  423.             // so change it. This will happen when we get a WM_SETCURSOR event
  424.             m_bSetHyperlinkCursor = TRUE;
  425.         }
  426. #elif defined(_MACINTOSH)
  427.         if (m_hHyperlinkCursor)
  428.         {
  429.             ::SetCursor(*m_hHyperlinkCursor);
  430.             m_eCurrentCursor = CURSOR_HYPERLINK;
  431.         }
  432. #elif defined(_UNIX) && defined(USE_XWINDOWS)
  433. if (m_pDisplay && m_hCurrentCursor != m_hHyperlinkCursor)
  434. {
  435.     XDefineCursor(m_pDisplay, m_Window, m_hHyperlinkCursor);
  436.     m_hCurrentCursor = m_hHyperlinkCursor;
  437. }
  438. #endif
  439.     }
  440.     else // if (bOverHyperlink)
  441.     {
  442.         // Clear the status bar
  443. if (m_pStatusMessage  &&
  444. // /Fixes PR 65008 (JPG, PNG versions): only set this to NULL
  445. // if we have recently set the status message, otherwise we
  446. // may cause SMIL's setting of the status message to be
  447. // overwritten with NULL, i.e., erased:
  448. m_bStatusMsgWillNeedErasing)
  449. {
  450.     m_bStatusMsgWillNeedErasing = FALSE;
  451.             m_pStatusMessage->SetStatus(NULL);
  452.         }
  453.         // Reset the cursor
  454. #if defined(_WINDOWS)
  455.         if(hCurrentCursor == m_hHyperlinkCursor)
  456.         {
  457.             // We are not over a hyperlink and out cursor IS the hyperlink cursor,
  458.             // so we need to change it back. This will happen when we get a WM_SETCURSOR event
  459.             m_bSetHyperlinkCursor = FALSE;
  460.         }
  461. #elif defined(_MACINTOSH)
  462.         if (m_eCurrentCursor == CURSOR_HYPERLINK)
  463.         {
  464.             ::InitCursor();
  465.             m_eCurrentCursor = CURSOR_ARROW;
  466.         }
  467. #elif defined(_UNIX) && defined(USE_XWINDOWS)
  468. if (m_pDisplay && m_hCurrentCursor == m_hHyperlinkCursor)
  469. {
  470.     XUndefineCursor(m_pDisplay, m_Window);
  471.     m_hCurrentCursor = 0;
  472. }
  473. #endif
  474.     }
  475.     return HXR_OK;
  476. }
  477. BOOL CRNVisualBaseRenderer::_IsValidRendererSurface()
  478. {
  479.     return m_pSite!=NULL;
  480. }
  481. void CRNVisualBaseRenderer::_AttachSite()
  482. {
  483.     //Empty base impl.
  484. }