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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: minisite.cpp,v 1.16.2.3 2004/07/09 01:59:28 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 "minisite.h"
  50. #include "hxvsurf.h"
  51. #include "hxtick.h"
  52. #include "minisurf.h"
  53. CMiniBaseSite::CMiniBaseSite(IUnknown* pContext,
  54.                              IUnknown* pUnkOuter,
  55.                              INT32 lZorder)
  56.     :  m_pContext(pContext),
  57.        m_pCCF(NULL),
  58.        m_pUser(NULL),
  59.        m_pWatcher(NULL),
  60.        m_pValues(NULL),
  61.        m_pVideoSurface(NULL),
  62.        m_pWindow(NULL),
  63.        m_lRefCount(0),
  64.        m_lZOrder(lZorder),
  65. #if defined (HELIX_FEATURE_SMIL_SITE)
  66.        m_pTopLevelSite(NULL),
  67.        m_pParentSite(NULL),
  68.        m_Region(NULL),
  69.        m_RegionWithoutChildren(NULL),
  70.        m_bIsVisible(TRUE),
  71.        m_CallbackHandle(0),
  72.        m_pScheduler(NULL),
  73.        m_bfCallBacks(0),
  74.        m_ulCallbackTime(0),
  75. #endif
  76.        m_bWindowCreatedByCreate(FALSE)
  77. {
  78.     memset(&m_size,      0, sizeof(m_size));
  79.     memset(&m_position , 0, sizeof(m_position ));
  80. #if defined (HELIX_FEATURE_SMIL_SITE)
  81.     m_pTopLevelSite = this;
  82.     memset(&m_topleft ,  0, sizeof(m_topleft ));
  83.     memset(&m_TopLevelWindow , 0, sizeof(m_TopLevelWindow ));
  84.     if( m_pContext )
  85.     {
  86.         m_pContext->QueryInterface(IID_IHXScheduler, (void**)&m_pScheduler);
  87.     }
  88.     HX_ASSERT(m_pScheduler);
  89. #endif
  90.     if(m_pContext)
  91.     {
  92.         m_pContext->AddRef();
  93.         
  94.         // get the CCF 
  95.         m_pContext->QueryInterface(IID_IHXCommonClassFactory,
  96.                                    (void**)&m_pCCF);
  97.         if( m_pCCF )
  98.         {
  99.             m_pCCF->CreateInstance(CLSID_IHXValues, (void**)&m_pValues);
  100.         }
  101.     }
  102.     m_pVideoSurface = CMiniBaseSurface::Create(m_pContext, this);
  103.     m_pVideoSurface->AddRef();
  104. }
  105. CMiniBaseSite::~CMiniBaseSite()
  106. {
  107.     // release intefaces
  108.     HX_RELEASE(m_pValues);
  109.     HX_RELEASE(m_pCCF);
  110.     HX_RELEASE(m_pContext);
  111.     HX_RELEASE(m_pVideoSurface);
  112. #if defined(HELIX_FEATURE_SMIL_SITE)
  113.     if( m_CallbackHandle )
  114.     {
  115.         if( m_pScheduler)
  116.             m_pScheduler->Remove(m_CallbackHandle);
  117.         m_CallbackHandle = 0;
  118.     }
  119.     HX_RELEASE(m_pScheduler);
  120.     
  121.     m_ChildrenInZOrder.RemoveAll();
  122.     //clean up passive site watchers
  123.     while(m_PassiveSiteWatchers.GetCount())
  124.     {
  125.         IHXPassiveSiteWatcher* pWatcher =
  126.             (IHXPassiveSiteWatcher*)m_PassiveSiteWatchers.GetHead();
  127.         HX_RELEASE(pWatcher);
  128.         m_PassiveSiteWatchers.RemoveHead();
  129.     }
  130.     
  131. #endif    
  132. }
  133. /************************************************************************
  134.  *  Method:
  135.  *    IUnknown::QueryInterface
  136.  */
  137. STDMETHODIMP CMiniBaseSite::QueryInterface(REFIID riid, void** ppvObj)
  138. {
  139.     if(IsEqualIID(riid, IID_IUnknown))
  140.     {
  141.         *ppvObj = (IUnknown*)(IHXSite*)this;
  142.     }
  143.     else if (IsEqualIID(riid, IID_IHXSite))
  144.     {
  145.         *ppvObj = (IHXSite*)this;
  146.     }
  147. #if defined (HELIX_FEATURE_SMIL_SITE)    
  148.     else if (IsEqualIID(riid, IID_IHXSite2))
  149.     {
  150.         *ppvObj = (IHXSite2*)this;
  151.     }
  152.     else if (IsEqualIID(riid, IID_IHXSiteControl))
  153.     {
  154.         *ppvObj = (IHXSiteControl*)this;
  155.     }
  156. #endif //HELIX_FEATURE_SMIL_SITE
  157.     
  158.     else if (IsEqualIID(riid, IID_IHXSiteWindowed))
  159.     {
  160.         *ppvObj = (IHXSiteWindowed*)this;
  161.     }
  162.     else if (m_pValues &&
  163.              m_pValues->QueryInterface(riid, ppvObj) == HXR_OK)
  164.     {
  165.         return HXR_OK;
  166.     }
  167.     else
  168.     {
  169.         *ppvObj = NULL;
  170.         return HXR_NOINTERFACE;
  171.     }
  172.     AddRef();
  173.     return HXR_OK;
  174. }
  175. /************************************************************************
  176.  *  Method:
  177.  *    IUnknown::AddRef
  178.  */
  179. STDMETHODIMP_(ULONG32) CMiniBaseSite::AddRef()
  180. {
  181.     return InterlockedIncrement(&m_lRefCount);
  182. }
  183. /************************************************************************
  184.  *  Method:
  185.  *    IUnknown::Release
  186.  */
  187. STDMETHODIMP_(ULONG32) CMiniBaseSite::Release()
  188. {
  189.     if (InterlockedDecrement(&m_lRefCount) > 0)
  190.     {
  191.         return m_lRefCount;
  192.     }
  193.     delete this;
  194.     return 0;
  195. }
  196. /************************************************************************
  197.  *  Method:
  198.  *    CMiniBaseSite::AttachWindow
  199.  */
  200. STDMETHODIMP CMiniBaseSite::AttachWindow(HXxWindow* pWindow)
  201. {
  202.     if (m_pWindow && m_pWindow->window)
  203.         return HXR_UNEXPECTED;
  204.     m_pWindow = pWindow;
  205. #if defined(HELIX_FEATURE_SMIL_SITE)
  206.     if (!m_pParentSite)
  207.     {
  208.         memcpy(&m_TopLevelWindow,
  209.                pWindow,
  210.                sizeof(HXxWindow)); /* Flawfinder: ignore */
  211.     }
  212. #endif
  213.     
  214.     _AttachWindow();
  215.     if (m_pUser)
  216.     {
  217.         // send HX_ATTACH_WINDOW msg to the renderers
  218.         void *  lpParam1 = NULL;
  219.         void *  lpParam2 = NULL;
  220.         HXxEvent event = {HX_ATTACH_WINDOW,
  221.                           m_pWindow ? m_pWindow->window : NULL,
  222.                           lpParam1, lpParam2,
  223.                           0, 0 };
  224.         m_pUser->HandleEvent(&event);     
  225.     }
  226.    
  227.     return HXR_OK;
  228. }
  229. /************************************************************************
  230.  *  Method:
  231.  *    IHXSiteWindowed::DetachWindow
  232.  */
  233. STDMETHODIMP CMiniBaseSite::DetachWindow()
  234. {
  235.     if (!m_pWindow || !m_pWindow->window)
  236.         return HXR_UNEXPECTED;
  237.     
  238.     if (m_pUser)
  239.     {
  240.         // send HX_DETACH_WINDOW msg to the renderers
  241.         void *  lpParam1 = NULL;
  242.         void *  lpParam2 = NULL;
  243.         HXxEvent event = {HX_DETACH_WINDOW, m_pWindow ? m_pWindow->window : NULL, lpParam1, lpParam2, 0, 0};
  244.  
  245.         m_pUser->HandleEvent(&event);
  246.     }
  247.     // let the OS specific site do its cleanup.
  248.     _DetachWindow();
  249.     m_pWindow = NULL;
  250. #if defined(HELIX_FEATURE_SMIL_SITE)
  251.     if (m_pTopLevelSite == this)
  252.     {
  253.         if (m_CallbackHandle)
  254.         {
  255.             if( m_pScheduler )
  256.                 m_pScheduler->Remove(m_CallbackHandle);
  257.             m_CallbackHandle = 0;
  258.         }
  259.     }
  260. #endif
  261.     return HXR_OK;
  262. }
  263. /************************************************************************
  264.  *  Method:
  265.  *    IHXSiteWindowed::Create
  266.  */
  267. STDMETHODIMP CMiniBaseSite::Create(void* ParentWindow, UINT32 style)
  268. {
  269.     HRESULT retVal = HXR_OK;
  270.     
  271.     if( m_pWindow && m_pWindow->window )
  272.     {
  273.         //We already have one.
  274.         return HXR_FAIL;
  275.     }
  276.    
  277.     void* hWnd = _Create(ParentWindow, style);
  278.     if (!hWnd)
  279.     {
  280.         retVal = HXR_FAIL;
  281.     }
  282.     else
  283.     {
  284.         HXxWindow* pWindow = new HXxWindow;
  285.         memset(pWindow,0,sizeof(HXxWindow));
  286.         pWindow->window = hWnd;
  287.         //This flags tells us if Create was used to make the window
  288.         //or not. We use this in SetSize and SetPosition so that we
  289.         //never resize or move the TLCs window. But, in TLC that call
  290.         //create, like testplay, we need to do the move and resize
  291.         //for them.
  292.         m_bWindowCreatedByCreate = TRUE;
  293.       
  294.         //This way we always pass through attach window.
  295.         AttachWindow(pWindow);
  296.     }
  297.     
  298.     return retVal;
  299. }
  300. /************************************************************************
  301.  *  Method:
  302.  *    IHXSiteWindowed::Destroy
  303.  */
  304. STDMETHODIMP CMiniBaseSite::Destroy() 
  305. {
  306.     //This could be the site that owns the overlay even though
  307.     //it doesn't have a window. Give it a chance to clean up
  308.     //here...
  309.     if( m_pVideoSurface )
  310.     {
  311.         m_pVideoSurface->EndOptimizedBlt();
  312.     }
  313.     
  314.     if(!m_pWindow || !m_pWindow->window)
  315.     {
  316.         return HXR_UNEXPECTED;
  317.     }
  318.     HXxWindow tempWindow;
  319.     memcpy( &tempWindow, m_pWindow, sizeof( HXxWindow ) ); /* Flawfinder: ignore */
  320.     DetachWindow();
  321.     _Destroy(&tempWindow);
  322.     m_pWindow = NULL;
  323.     return HXR_OK;
  324. }
  325. STDMETHODIMP_(HXxWindow*) CMiniBaseSite::GetWindow() 
  326. {
  327.     HXxWindow* pRet = m_pWindow;
  328. #if defined(HELIX_FEATURE_SMIL_SITE)    
  329.     if( m_pTopLevelSite != this && m_pParentSite )
  330.         pRet = m_pParentSite->GetWindow();
  331. #endif    
  332.     return pRet;
  333. }
  334. /************************************************************************
  335.  *  Method:
  336.  *    IHXSite::AttachUser
  337.  */
  338. STDMETHODIMP CMiniBaseSite::AttachUser(IHXSiteUser* /*IN*/ pUser)
  339. {
  340.     if (m_pUser)
  341.         return HXR_UNEXPECTED;
  342.     m_pUser = pUser;
  343.     m_pUser->AddRef();
  344.     m_pUser->AttachSite(this);
  345.     /*if (m_bAttachWindowPending)
  346.       {
  347.       m_bAttachWindowPending = FALSE;
  348.       m_bDetachWndMsgPending = TRUE;
  349.       // send HX_ATTACH_WINDOW msg to the renderers
  350.       void *  lpParam1 = NULL;
  351.       void *  lpParam2 = NULL;
  352.       HXxEvent event = {HX_ATTACH_WINDOW, m_pWindow ? m_pWindow->window : NULL, lpParam1, lpParam2, 0, 0};
  353.       m_pUser->HandleEvent(&event);     
  354.       }*/
  355.     return HXR_OK;
  356. }
  357. /************************************************************************
  358.  *  Method:
  359.  *    IHXSite::DetachUser
  360.  */
  361. STDMETHODIMP CMiniBaseSite::DetachUser()
  362. {
  363.     if (!m_pUser)
  364.         return HXR_UNEXPECTED;
  365. #if defined(HELIX_FEATURE_SMIL_SITE)
  366.     if (m_CallbackHandle)
  367.     {
  368.         if( m_pScheduler)
  369.             m_pScheduler->Remove(m_CallbackHandle);
  370.         m_CallbackHandle = 0;
  371.     }
  372. #endif
  373.     AddRef();
  374.     if (HXR_OK == m_pUser->DetachSite())
  375.     {
  376.         HX_RELEASE(m_pUser);
  377.     }
  378.     Release();
  379.     return HXR_OK;
  380. }
  381. /************************************************************************
  382.  *  Method:
  383.  *    IHXSite::GetUser
  384.  */
  385. STDMETHODIMP CMiniBaseSite::GetUser(REF(IHXSiteUser*) /*OUT*/ pUser)
  386. {
  387.     if (!m_pUser)
  388.         return HXR_UNEXPECTED;
  389.     pUser = m_pUser;
  390.     pUser->AddRef();
  391.     return HXR_OK;
  392. }
  393. /************************************************************************
  394.  *  Method:
  395.  *    IHXSite::CreateChild
  396.  */
  397. STDMETHODIMP CMiniBaseSite::CreateChild(REF(IHXSite*) /*OUT*/ pChildSite)
  398. {
  399.     HRESULT result = HXR_NOTIMPL;
  400. #if defined (HELIX_FEATURE_SMIL_SITE)
  401.     // Create an instance of CMiniBaseSite, let it know it's in child
  402.     // window mode.
  403.     CMiniBaseSite* pChildSiteWindowless =
  404.         CMiniBaseSite::CreateSite(m_pContext, NULL, m_ChildrenInZOrder.GetCount());
  405.     pChildSiteWindowless->SetParentSite(this);
  406.     pChildSiteWindowless->SetTopLevelSite(m_pTopLevelSite);
  407.     pChildSiteWindowless->SetParentWindow(&m_TopLevelWindow);
  408.     // Get the IHXSite interface from the child to return to the
  409.     // outside world.
  410.     pChildSiteWindowless->QueryInterface(IID_IHXSite, (void**)&pChildSite);
  411.     //Add it to our children list
  412.     m_ChildrenInZOrder.AddTail(pChildSite);
  413.     //Make sure it has the lowest z-order.
  414.     pChildSiteWindowless->SetInternalZOrder(m_ChildrenInZOrder.GetCount());
  415.     
  416.     //Set the child's origin
  417.     pChildSiteWindowless->SetOrigin(&m_topleft);
  418.     //Let subclasses do any platform specific work.
  419.     _ChildCreated();
  420.     
  421.     result = HXR_OK;
  422. #endif
  423.     return result;
  424. }
  425. /************************************************************************
  426.  *  Method:
  427.  *    IHXSite::DestroyChild
  428.  */
  429. STDMETHODIMP CMiniBaseSite::DestroyChild(IHXSite* /*IN*/ pChildSite)
  430. {
  431.     HX_RESULT res = HXR_FAIL;
  432. #ifdef HELIX_FEATURE_SMIL_SITE
  433.     //Find this child and remove it from our list
  434.     LISTPOSITION pos = m_ChildrenInZOrder.Find((void*)pChildSite);
  435.     if(pos)
  436.     {
  437.         res = HXR_OK;
  438.         CMiniBaseSite* pSite = (CMiniBaseSite*)m_ChildrenInZOrder.GetAt(pos);
  439.         m_ChildrenInZOrder.RemoveAt(pos);
  440.     }
  441. #endif
  442.     return res;
  443. }
  444. /************************************************************************
  445.  *  Method:
  446.  *    IHXSite::AttachWatcher
  447.  */
  448. STDMETHODIMP CMiniBaseSite::AttachWatcher(IHXSiteWatcher* /*IN*/ pWatcher)
  449. {
  450.     if (m_pWatcher)
  451.         return HXR_UNEXPECTED;
  452.     m_pWatcher = pWatcher;
  453.     if (m_pWatcher)
  454.     {
  455.         m_pWatcher->AddRef();
  456.         m_pWatcher->AttachSite(this);
  457.     }
  458.     return HXR_OK;
  459. }
  460. /************************************************************************
  461.  *  Method:
  462.  *    IHXSite::DetachWatcher
  463.  */
  464. STDMETHODIMP CMiniBaseSite::DetachWatcher()
  465. {
  466.     if (!m_pWatcher)
  467.         return HXR_UNEXPECTED;
  468.     m_pWatcher->DetachSite();
  469.     HX_RELEASE(m_pWatcher);
  470.     return HXR_OK;
  471. }
  472. /************************************************************************
  473.  *  Method:
  474.  *    IHXSite::SetSize
  475.  */
  476. STDMETHODIMP CMiniBaseSite::SetSize(HXxSize size)
  477. {
  478.     HRESULT hres = HXR_OK;
  479. #if defined (HELIX_FEATURE_SMIL_SITE)
  480.     CHXSimpleList::Iterator i;
  481.     
  482.     size.cx = size.cx<0?0:size.cx;
  483.     size.cy = size.cy<0?0:size.cy;
  484.     //before we do anything, we give the SiteWatcher a chance to
  485.     //influence this operation.
  486.     if (m_pWatcher)
  487.     {
  488.         hres = m_pWatcher->ChangingSize(m_size, size);
  489.     }
  490.     
  491.     if (HXR_OK == hres )
  492.     {
  493.         m_size = size;
  494.         
  495.         // iterate child site list 
  496.         for(i=m_PassiveSiteWatchers.Begin(); i!= m_PassiveSiteWatchers.End(); ++i)
  497.         {
  498.             ((IHXPassiveSiteWatcher*) *i)->SizeChanged(&m_size);
  499.         }
  500.         if( m_pWindow && m_pWindow->window &&
  501.             (m_pTopLevelSite!=this || m_bWindowCreatedByCreate ) )
  502.         {
  503.             _SetSize(size);
  504.         }
  505.     }
  506.     if (m_pTopLevelSite==this)  
  507.     {
  508.         m_pTopLevelSite->RecomputeClip();
  509.     } 
  510.     else
  511.     {
  512.         if(m_pTopLevelSite)
  513.             m_pTopLevelSite->ScheduleCallback(CLIP, 0);
  514.     }
  515. #else
  516.     m_size = size;
  517.     _SetSize(m_size);
  518. #endif   
  519.     return hres;
  520. }
  521. /************************************************************************
  522.  *  Method:
  523.  *    IHXSite::SetPosition
  524.  */
  525. STDMETHODIMP CMiniBaseSite::SetPosition(HXxPoint position)
  526. {
  527.     HRESULT hres = HXR_OK;
  528. #if defined (HELIX_FEATURE_SMIL_SITE)
  529.     CHXSimpleList::Iterator i;
  530.     CHXMapPtrToPtr::Iterator j;
  531.     //Before we do anything, we give the SiteWatcher a chance to
  532.     //influence this operation.
  533.     if (m_pWatcher)
  534.     {
  535.         hres = m_pWatcher->ChangingPosition(m_position, position);
  536.     }
  537.     if (HXR_OK == hres)
  538.     {
  539.         if(!m_bWindowCreatedByCreate )
  540.         {
  541.             // if we've created the window we don't want to move the site
  542.             // just the window
  543.             m_position = position;
  544.         }
  545.         
  546.         //fixup our top left
  547.         ResetOrigin();
  548.         //iterate passive site watcher list 
  549.         for(i=m_PassiveSiteWatchers.Begin(); i!= m_PassiveSiteWatchers.End(); ++i)
  550.         {
  551.             ((IHXPassiveSiteWatcher*) *i)->PositionChanged(&m_position);
  552.         }
  553.         if( m_pWindow &&
  554.             m_pWindow->window &&
  555.             (m_pTopLevelSite!=this || m_bWindowCreatedByCreate )
  556.             )
  557.         {
  558.             _SetPosition(position);
  559.         }
  560.     }
  561.     if (m_pTopLevelSite==this)
  562.     {
  563.         m_pTopLevelSite->RecomputeClip();
  564.     }
  565.     else
  566.     {
  567.         if (m_pTopLevelSite)
  568.         {
  569.             m_pTopLevelSite->ScheduleCallback(CLIP, 0);
  570.         }
  571.     }
  572. #else
  573.     m_position = position;
  574.     _SetPosition(m_position);
  575. #endif    
  576.     return hres;
  577. }
  578. /************************************************************************
  579.  *  Method:
  580.  *    IHXSite::GetSize
  581.  */
  582. STDMETHODIMP CMiniBaseSite::GetSize(REF(HXxSize) size)
  583. {
  584.     size = m_size;
  585.     return HXR_OK;
  586. }
  587. /************************************************************************
  588.  *  Method:
  589.  *    IHXSite::GetPosition
  590.  */
  591. STDMETHODIMP CMiniBaseSite::GetPosition(REF(HXxPoint) position)
  592. {
  593.     position = m_position;
  594.     return HXR_OK;
  595. }
  596. /************************************************************************
  597.  *  Method:
  598.  *    IHXSite::DamageRect
  599.  */
  600. STDMETHODIMP CMiniBaseSite::DamageRect(HXxRect rect)
  601. {
  602.     return HXR_OK;
  603. }
  604. /************************************************************************
  605.  *  Method:
  606.  *    IHXSite::DamageRegion
  607.  */
  608. STDMETHODIMP CMiniBaseSite::DamageRegion(HXxRegion region)
  609. {
  610.     return HXR_OK;
  611. }
  612. /************************************************************************
  613.  *  Method:
  614.  *    IHXSite::ForceRedraw
  615.  */
  616. STDMETHODIMP CMiniBaseSite::ForceRedraw()
  617. {
  618.     
  619.     if(m_pUser)
  620.     {
  621.         HXxEvent event;
  622.         HXxWindow* hxxWin = GetWindow();
  623.         event.event   = HX_SURFACE_UPDATE;
  624.         event.window  = m_pWindow ? m_pWindow->window : NULL;
  625.         event.param1  = m_pVideoSurface;
  626.         event.param2  = NULL;
  627.         event.result  = 0;
  628.         event.handled = 0;
  629.         m_pUser->HandleEvent(&event);
  630.     }
  631.     return HXR_OK;
  632. }
  633. #if defined (HELIX_FEATURE_SMIL_SITE)
  634. STDMETHODIMP CMiniBaseSite::ForceRedrawAll()
  635. {
  636.     HX_RESULT retVal = HXR_OK;
  637.     _ForceRedrawAll();
  638.     return retVal;
  639. }
  640. /************************************************************************
  641.  *  Method:
  642.  *    IHXSite2::UpdateSiteWindow
  643.  *      
  644.  *      Not used on Windows platform
  645.  */
  646. STDMETHODIMP CMiniBaseSite::UpdateSiteWindow
  647. (
  648.     HXxWindow* /*IN*/ pWindow
  649.     )
  650. {
  651.     return HXR_NOTIMPL;
  652. }
  653. /************************************************************************
  654.  *  Method:
  655.  *    IHXSite2::ShowSite
  656.  */
  657. STDMETHODIMP CMiniBaseSite::ShowSite(BOOL bShow)
  658. {
  659.     HX_RESULT res = HXR_OK;
  660. #ifdef HELIX_FEATURE_SMIL_SITE    
  661.     if(m_bIsVisible != bShow)
  662.     {
  663.         m_bIsVisible = bShow;
  664.         if( this == m_pTopLevelSite )
  665.         {
  666.             RecomputeClip();
  667.         }
  668.         else
  669.         {
  670.             if(m_pTopLevelSite)
  671.                 m_pTopLevelSite->ScheduleCallback(CLIP, 0);
  672.         }
  673.     }
  674.     res = HXR_OK;
  675. #endif
  676.     return res;
  677. }
  678. /************************************************************************
  679.  *  Method:
  680.  *    IHXSite2::MoveSiteToTop
  681.  */
  682. STDMETHODIMP CMiniBaseSite::MoveSiteToTop()
  683. {
  684.     SetZOrder(-1); //-1 means the top.
  685.     return HXR_OK; 
  686. }
  687. /************************************************************************
  688.  *  Method:
  689.  *    IHXSite2::GetVideoSurface
  690.  */
  691. STDMETHODIMP CMiniBaseSite::GetVideoSurface(REF(IHXVideoSurface*) pSurface)
  692. {
  693.     HX_RESULT res = HXR_FAIL;
  694.     if (m_pVideoSurface)
  695.     {
  696.         res = m_pVideoSurface->QueryInterface(IID_IHXVideoSurface, 
  697.                                               (void**)&pSurface);
  698.     }
  699.     return res;
  700. }
  701. /************************************************************************
  702.  *  Method:
  703.  *    IHXSite2::AddPassiveSiteWatcher
  704.  */
  705. STDMETHODIMP CMiniBaseSite::AddPassiveSiteWatcher(IHXPassiveSiteWatcher* pWatcher)
  706. {
  707.     pWatcher->AddRef();
  708.     m_PassiveSiteWatchers.AddTail(pWatcher);
  709.     return HXR_OK;
  710. }
  711. /************************************************************************
  712.  *  Method:
  713.  *    IHXSite2::RemovePassiveSiteWatcher
  714.  */
  715. STDMETHODIMP CMiniBaseSite::RemovePassiveSiteWatcher(IHXPassiveSiteWatcher* pWatcher)
  716. {
  717.     // iterate child site list 
  718.     IHXPassiveSiteWatcher* pThisWatcher = NULL;
  719.     LISTPOSITION pPos = m_PassiveSiteWatchers.Find(pWatcher);
  720.     HX_RESULT retVal = HXR_FAIL;
  721.     if (pPos)
  722.     {
  723.         m_PassiveSiteWatchers.RemoveAt(pPos);
  724.         HX_RELEASE(pWatcher);
  725.         retVal = HXR_OK;
  726.     }
  727.     return retVal;
  728. }
  729. /************************************************************************
  730.  *  Method:
  731.  *    IHXSite2::SetCursor
  732.  */
  733. STDMETHODIMP CMiniBaseSite::SetCursor(HXxCursor cursor, REF(HXxCursor) oldCursor)
  734. {
  735.     return HXR_NOTIMPL;
  736. }
  737. STDMETHODIMP CMiniBaseSite::SetZOrder(INT32 lZOrder)
  738. {
  739.     if(!m_pParentSite) 
  740.     {
  741.         return HXR_UNEXPECTED;
  742.     }
  743.     if (lZOrder == -1)
  744.     {
  745.         lZOrder = m_pParentSite->GetNumberOfChildSites() - 1; 
  746.     }
  747.     
  748.     if (lZOrder >= (INT32) m_pParentSite->GetNumberOfChildSites())
  749.     {
  750.         lZOrder = m_pParentSite->GetNumberOfChildSites() - 1;
  751.     }
  752.     if (m_lZOrder != lZOrder)
  753.     {
  754.         m_pParentSite->UpdateZOrder(this, lZOrder);
  755.     }
  756.     if( this == m_pTopLevelSite)
  757.     {
  758.         RecomputeClip();
  759.     }
  760.     else
  761.     {
  762.         if (m_pTopLevelSite)
  763.             m_pTopLevelSite->ScheduleCallback(CLIP, 0);
  764.     }
  765.     return HXR_OK;
  766. }
  767. void CMiniBaseSite::UpdateZOrder( CMiniBaseSite* pUpdatedChildSite,INT32 lNewZOrder)
  768. {
  769.     HX_ASSERT(pUpdatedChildSite);
  770.     LISTPOSITION pos = m_ChildrenInZOrder.Find((void*)pUpdatedChildSite);
  771.     if (!pos)
  772.     {
  773.         return;
  774.     }
  775.     
  776.     m_ChildrenInZOrder.RemoveAt(pos);
  777.     
  778.     BOOL bHasReinsertedChild = FALSE;
  779.     INT32 zOrder = 0;
  780.     INT32 newZOrder = 0;
  781.     LISTPOSITION posNext = m_ChildrenInZOrder.GetHeadPosition();
  782.     while (posNext)
  783.     {
  784.         pos = posNext;
  785.         CMiniBaseSite* pSite = (CMiniBaseSite*)m_ChildrenInZOrder.GetNext(posNext);
  786.         if (!bHasReinsertedChild)
  787.         {
  788.             pSite->GetZOrder(zOrder);
  789.             
  790.             if (zOrder > lNewZOrder)
  791.             {
  792.                 m_ChildrenInZOrder.InsertBefore(pos, (void*)pUpdatedChildSite);
  793.                 bHasReinsertedChild = TRUE;
  794.                 pUpdatedChildSite->SetInternalZOrder(newZOrder++);
  795.             }
  796.         }
  797.         pSite->SetInternalZOrder(newZOrder++);
  798.     }
  799.     
  800.     if (!bHasReinsertedChild)
  801.     {
  802.         m_ChildrenInZOrder.AddTail((void*)pUpdatedChildSite);
  803.         pUpdatedChildSite->SetInternalZOrder(newZOrder++);
  804.     }
  805. }
  806. void CMiniBaseSite::RecomputeClip()
  807. {
  808.     // this recomputes our clipping rect.
  809.     if( ComputeSubRects() )
  810.     {
  811.         //We need to do this in Z-Order.
  812.         LISTPOSITION pos = m_ChildrenInZOrder.GetHeadPosition();
  813.         while(pos)
  814.         {
  815.             CMiniBaseSite* pSite = (CMiniBaseSite*)m_ChildrenInZOrder.GetNext(pos);
  816.             pSite->RecomputeClip();
  817.         }
  818.     }
  819. }
  820. BOOL CMiniBaseSite::IsSiteVisible()
  821. {
  822.     BOOL bIsVisible = m_bIsVisible;
  823.     if(m_pParentSite)
  824.     {
  825.         bIsVisible &= m_pParentSite->IsSiteVisible();
  826.     }
  827.     if( bIsVisible )
  828.     {
  829.         //If we are a m_bSiteNeverBlts then it doesn't matter if we are
  830.         //visible or not, we must have at least one child that is
  831.         //visible and not m_bSiteNeverBlts. Otherwise we really aren't
  832.         //visible at all. This distinction is needed because of our
  833.         //favorite logic in computesubrecs not that we have transparent
  834.         //regions.
  835.         if(!_CheckForVisibleChild())
  836.         {
  837.             bIsVisible = FALSE;
  838.         }
  839.     }
  840.     return bIsVisible;
  841. }
  842. BOOL CMiniBaseSite::_CheckForVisibleChild()
  843. {
  844.     BOOL       retVal = FALSE;
  845.     BOOL       bSiteNeverBlts = FALSE;
  846.     IHXBuffer* pBuf=NULL;
  847.     m_pValues->GetPropertyCString( "SiteNeverBlts", pBuf );
  848.     if( pBuf )
  849.     {
  850.         bSiteNeverBlts = atoi( (const char*)pBuf->GetBuffer() )==1;
  851.         HX_RELEASE(pBuf);
  852.     }
  853.     
  854.     if( m_bIsVisible && !bSiteNeverBlts )
  855.     {
  856.         retVal = TRUE;
  857.     }
  858.     else
  859.     {
  860.         LISTPOSITION pos = m_ChildrenInZOrder.GetHeadPosition();
  861.         while(pos)
  862.         {
  863.             CMiniBaseSite* pSite = (CMiniBaseSite*)m_ChildrenInZOrder.GetNext(pos);
  864.             if( pSite->_CheckForVisibleChild() )
  865.             {
  866.                 retVal = TRUE;
  867.                 break;
  868.             }
  869.         }
  870.     }
  871.     return retVal;
  872. }
  873. BOOL CMiniBaseSite::ComputeSubRects()
  874. {
  875.     BOOL         retVal          = TRUE;        
  876.     HXREGION*    hTemp           = NULL;
  877.     HXxSize      size;
  878.     HXxPoint*    pPosition       = NULL;
  879.     LISTPOSITION pos             = NULL;
  880.     if (m_Region)
  881.     {
  882.         HXDestroyRegion(m_Region);
  883.         m_Region = NULL;
  884.     }
  885.     if (m_RegionWithoutChildren)
  886.     {
  887.         HXDestroyRegion(m_RegionWithoutChildren);
  888.         m_RegionWithoutChildren = NULL;
  889.     }
  890.     if( IsSiteVisible() )
  891.     {
  892.         m_RegionWithoutChildren = HXCreateRectRegion(m_topleft.x,
  893.                                                      m_topleft.y,
  894.                                                      m_size.cx, 
  895.                                                      m_size.cy
  896.                                                      );
  897.         if (m_pParentSite)
  898.             m_pParentSite->BuildParnetClipping(m_RegionWithoutChildren,this);
  899.         // subtract all of my children from my clipping region
  900.         m_Region = HXCreateRectRegion(0,0,0,0);
  901.         HXUnionRegion(m_Region, m_RegionWithoutChildren, m_Region);
  902.         if (m_Region->numRects == 0)
  903.         {
  904.             retVal = FALSE;
  905.         }
  906.         else
  907.         {
  908.             pos = m_ChildrenInZOrder.GetHeadPosition();
  909.             while(pos)
  910.             {
  911.                 CMiniBaseSite* pSite = (CMiniBaseSite*) m_ChildrenInZOrder.GetNext(pos);
  912.                 if(pSite->IsSiteVisible())
  913.                 {    
  914.                     pPosition = pSite->GetOrigin();
  915.                     pSite->GetSize(size);
  916.                     hTemp = HXCreateRectRegion( pPosition->x,
  917.                                                 pPosition->y,
  918.                                                 size.cx, 
  919.                                                 size.cy);
  920.                     
  921.                     HXSubtractRegion(m_Region, hTemp, m_Region);
  922.                     HXDestroyRegion(hTemp);
  923.                     hTemp = NULL;
  924.                 }
  925.             }
  926.         }
  927.     }
  928.     else
  929.     {
  930.         m_RegionWithoutChildren = HXCreateRectRegion(0,0,0,0);
  931.         m_Region                = HXCreateRectRegion(0,0,0,0);
  932.     }
  933.     return TRUE;
  934. }
  935. void CMiniBaseSite::BuildParnetClipping(HXREGION* hClip, CMiniBaseSite* pChild)
  936. {
  937.     HXREGION* hTemp     = NULL;
  938.     HXxPoint* pPosition = NULL;
  939.     HXxSize   size;
  940.     BOOL      bFound    = FALSE;
  941.     // subtract all of my children from my clipping region
  942.     LISTPOSITION pos = m_ChildrenInZOrder.GetHeadPosition();
  943.     while(pos)
  944.     {
  945.         CMiniBaseSite* pSite = (CMiniBaseSite*)m_ChildrenInZOrder.GetNext(pos);
  946.         //Keep in mind that all sites before pChild have zorder less than
  947.         //pChild and all sites after have a higher zorder.
  948.         if( pChild == pSite )
  949.         {
  950.             bFound = TRUE;
  951.         }
  952.         if(bFound && pChild!=pSite && pSite->IsSiteVisible())
  953.         {
  954.             pSite->GetSize(size);
  955.             pPosition = pSite->GetOrigin();
  956.             hTemp = HXCreateRectRegion( pPosition->x,
  957.                                         pPosition->y,
  958.                                         size.cx, 
  959.                                         size.cy);
  960.             HXSubtractRegion(hClip, hTemp, hClip);
  961.             HXDestroyRegion(hTemp);
  962.             hTemp=NULL;
  963.         }
  964.     }
  965.     // now handle my clipping region
  966.     hTemp = HXCreateRectRegion(m_topleft.x,
  967.                                m_topleft.y,
  968.                                m_size.cx, 
  969.                                m_size.cy);
  970.     
  971.     HXIntersectRegion(hClip, hTemp, hClip);
  972.     HXDestroyRegion(hTemp);
  973.     hTemp=NULL;
  974.     
  975.     if (m_pParentSite)
  976.         m_pParentSite->BuildParnetClipping(hClip,this);
  977. }
  978. void CMiniBaseSite::ScheduleCallback(CALLBACK_TYPE nWhichCallback,
  979.                                    INT32 nMilliseconds)
  980. {
  981.     HX_ASSERT(m_pTopLevelSite == this);
  982.     if( !(m_bfCallBacks & nWhichCallback))
  983.     {
  984.         //It is not already set.
  985.         m_bfCallBacks |= nWhichCallback;
  986.         
  987.         if (m_pScheduler)
  988.         {
  989.             ULONG32 now = HX_GET_TICKCOUNT();
  990.             if(m_CallbackHandle && m_ulCallbackTime>(now+nMilliseconds) )
  991.             {
  992.                 m_pScheduler->Remove(m_CallbackHandle);
  993.                 m_CallbackHandle = 0;
  994.             }
  995.             if( !m_CallbackHandle )
  996.             {
  997.                 //Don't schedule a new one if we are already waiting.
  998.                 m_CallbackHandle = m_pScheduler->RelativeEnter( this,
  999.                                                                 nMilliseconds);
  1000.                 m_ulCallbackTime = now+nMilliseconds;
  1001.             }
  1002.         }
  1003.     }
  1004. }
  1005. STDMETHODIMP CMiniBaseSite::Func(void)
  1006. {
  1007.     m_CallbackHandle = 0;
  1008.     AddRef();
  1009.     if( m_bfCallBacks & CLIP )
  1010.     {
  1011.         RecomputeClip();
  1012.         _ForceRedrawAll();
  1013.         m_bfCallBacks &= ~CLIP;
  1014.         m_bfCallBacks &= ~REDRAW_ALL;
  1015.     }
  1016.     if (m_bfCallBacks & REPAINT)
  1017.     {
  1018.         _ForceRedrawAll();
  1019.         m_bfCallBacks &= ~REPAINT;
  1020.     }
  1021.     if( m_bfCallBacks & REDRAW_ALL )
  1022.     {
  1023.         _ForceRedrawAll();
  1024.         m_bfCallBacks &= ~REDRAW_ALL;
  1025.     }
  1026.     Release();
  1027.     return HXR_OK;
  1028. }
  1029. void CMiniBaseSite::_ForceRedrawAll()
  1030. {
  1031.     if( (IsSiteVisible() && m_Region && !HXEmptyRegion(m_Region)))
  1032.     {
  1033.         ForceRedraw();
  1034.     }
  1035.    
  1036.     //Now do all the children in z-order
  1037.     LISTPOSITION pos = m_ChildrenInZOrder.GetHeadPosition();
  1038.     while(pos)
  1039.     {
  1040.         CMiniBaseSite* pSite = (CMiniBaseSite*)m_ChildrenInZOrder.GetNext(pos);
  1041.         pSite->_ForceRedrawAll();
  1042.     }
  1043. }
  1044. void CMiniBaseSite::ResetOrigin()
  1045. {
  1046.     m_topleft.x =0;
  1047.     m_topleft.y =0;
  1048.     GetAbsoluteCords(m_topleft);
  1049.    
  1050.     LISTPOSITION pos = m_ChildrenInZOrder.GetHeadPosition();
  1051.     while(pos)
  1052.     {
  1053.         CMiniBaseSite* pChildSite = (CMiniBaseSite*)m_ChildrenInZOrder.GetNext(pos);
  1054.         pChildSite->ResetOrigin();
  1055.     }
  1056. }
  1057. void CMiniBaseSite::GetAbsoluteCords(HXxPoint& point)
  1058. {
  1059.     point.x += m_position.x;
  1060.     point.y += m_position.y;
  1061.     if (m_pParentSite)
  1062.     {
  1063.         m_pParentSite->GetAbsoluteCords(point);
  1064.     }
  1065. }
  1066. #endif //HELIX_FEATURE_SMIL_SITE