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

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 <X11/Xlib.h>
  36. #include <X11/Xutil.h>
  37. #include <X11/Intrinsic.h>
  38. #include "hxcom.h"
  39. #include "hxtypes.h"
  40. #include "hxwintyp.h"
  41. #include "hxmap.h"
  42. #include "hxslist.h"
  43. #include "ihxpckts.h"
  44. #include "hxwin.h"
  45. #include "hxengin.h"
  46. #include "hxsite2.h"
  47. #include "chxxtype.h"
  48. #include "hxvctrl.h"
  49. #include "hxvsurf.h"
  50. #include "hxcodec.h"
  51. #include "surface.h"
  52. #include "vidosurf.h"
  53. #include "chxpckts.h"
  54. #include "hxevent.h"
  55. #include "sitemgr.h"
  56. #include "sitetext.h"
  57. //#include "pnmm.h" ??
  58. #define DEF_TEXT_HEIGHT 12
  59. #define POINTS_TO_PIXELS 1.5
  60. #define DEF_TEXT_GUTTER 1.2
  61. #define DEF_STAT_HEIGHT (int)((double)DEF_TEXT_HEIGHT * POINTS_TO_PIXELS * DEF_TEXT_GUTTER)
  62. #define DEF_HORZ_GUTTER 4
  63. #define ELIPSIS "..."
  64. #define ELIPSIS_LEN 3
  65. // fwd declares 
  66. typedef ULONG32 COLORTYPE;
  67. CHXSiteStatusText::CHXSiteStatusText()
  68.    : m_lRefCount(0)
  69.    , m_pSite(NULL)
  70.    , m_pParentSite(NULL)
  71.    , m_rgbBkgndColor(0x00008000)
  72.    , m_rgbTextColor(0x0000FF00)
  73.    , m_colormap(0)
  74.    , m_display(0)
  75.    , m_window(0)
  76.    , m_statusfont(NULL)
  77. {
  78.    memset(&m_statusPos, 0, sizeof(HXxPoint));
  79.    memset(&m_statusSize, 0, sizeof(HXxSize));
  80. }
  81.     
  82. CHXSiteStatusText::~CHXSiteStatusText()
  83. {
  84.    Destroy(); // make sure we cleanup
  85. }
  86. HX_RESULT CHXSiteStatusText::Create(IHXSite* pSite)
  87. {
  88.    IHXSite* pChildSite = NULL;
  89.    HX_RESULT  hr = HXR_FAIL;
  90.     
  91.    HX_ASSERT(pSite);
  92.    HX_ASSERT(!m_pSite);
  93.     
  94.    // keep a ref while we use the parent site
  95.    pSite->AddRef();
  96.     
  97.    if (pSite->CreateChild(pChildSite) == HXR_OK)
  98.    {
  99.       if (pChildSite->AttachUser(this) == HXR_OK)
  100.       {
  101.          m_pParentSite = pSite;
  102.          if (m_StatusText.IsEmpty())
  103.          {
  104.             Hide(); // keep hidden until we have status text
  105.          }
  106.          else
  107.          {
  108.             Show();
  109.          }
  110.          UpdatePosition();
  111.          hr = HXR_OK;
  112.       }
  113.       HX_RELEASE(pChildSite);
  114.    }
  115.    // release if we failed
  116.    if (hr != HXR_OK)
  117.    {
  118.       HX_RELEASE(pSite);
  119.    }
  120.    return hr;
  121. }
  122. HX_RESULT CHXSiteStatusText::Destroy()
  123. {
  124.    if (m_pSite)
  125.    {
  126.       if (m_pParentSite)
  127.       {
  128.          m_pParentSite->DestroyChild(m_pSite);
  129.       }
  130.       // DetachUser will call DetachSite, which will release m_pSite
  131.       m_pSite->DetachUser();
  132.       m_pSite == NULL;
  133.    }
  134.    HX_RELEASE(m_pParentSite);
  135.     
  136.    return HXR_OK;
  137. }
  138.  
  139. HX_RESULT CHXSiteStatusText::Show()
  140. {
  141.    IHXSite2* pSite2 = NULL;
  142.     
  143.    if (GetIHXSite2(pSite2) == HXR_OK)
  144.    {
  145.       pSite2->ShowSite(TRUE);
  146.       HX_RELEASE(pSite2);
  147.    }
  148.    
  149.    BringToTop();
  150.    
  151.    return HXR_OK;
  152. }
  153. HX_RESULT CHXSiteStatusText::Hide()
  154. {
  155.    IHXSite2* pSite2 = NULL;
  156.     
  157.    if (GetIHXSite2(pSite2) == HXR_OK)
  158.    {
  159.       pSite2->ShowSite(FALSE);
  160.       HX_RELEASE(pSite2);
  161.    }
  162.     
  163.    return HXR_OK;
  164. }
  165. HX_RESULT CHXSiteStatusText::ParentChangedSize()
  166. {
  167.    UpdatePosition();
  168.    return HXR_OK;
  169. }
  170. HX_RESULT CHXSiteStatusText::BringToTop()
  171. {
  172.    IHXSite2* pSite2 = NULL;
  173.     
  174.    if (GetIHXSite2(pSite2) == HXR_OK)
  175.    {
  176.       pSite2->MoveSiteToTop();
  177.       HX_RELEASE(pSite2);
  178.    }
  179.     
  180.    return HXR_OK;
  181. }
  182. HX_RESULT CHXSiteStatusText::UpdatePosition()
  183. {
  184.    HXxPoint parentPos;
  185.    HXxSize parentSize;
  186.    HX_RESULT    res = HXR_FAIL;
  187.     
  188.    if (m_pParentSite && m_pSite)
  189.    {
  190.       if (m_pParentSite->GetSize(parentSize) == HXR_OK &&
  191.           m_pParentSite->GetPosition(parentPos) == HXR_OK)
  192.       {
  193.          // call platform-specific code to adjust the position & size
  194.          // of our site (since fonts may require different heights on
  195.          // different platforms
  196.          _AdjustPosition(&parentPos, &parentSize);
  197.          m_pSite->SetPosition(m_statusPos);
  198.          m_pSite->SetSize(m_statusSize);
  199.          
  200.          if (!m_StatusText.IsEmpty())
  201.          {
  202.             BringToTop();
  203.          }
  204.          res = HXR_OK;
  205.       }
  206.    }
  207.     
  208.    return res;
  209. }
  210. void CHXSiteStatusText::SetStatusText(const char* pText)
  211. {
  212.    m_StatusText = pText;
  213.    if (m_StatusText.IsEmpty())
  214.    {
  215.       Hide();
  216.    }
  217.    else
  218.    {
  219.       Show();
  220.    }
  221. }
  222.     
  223. STDMETHODIMP CHXSiteStatusText::QueryInterface(REFIID riid, void** ppvObj)
  224. {
  225.    if (riid == IID_IHXSiteUser)
  226.    {
  227.       *ppvObj = (IHXSiteUser*)this;
  228.       AddRef();
  229.       return HXR_OK;
  230.    }
  231.    if (riid == IID_IHXSiteWatcher)
  232.    {
  233.       *ppvObj = (IHXSiteWatcher*)this;
  234.       AddRef();
  235.       return HXR_OK;
  236.    }
  237.    else if (riid == IID_IUnknown)
  238.    {
  239.       *ppvObj = (IUnknown*)(IHXSiteUser*)this;
  240.       AddRef();
  241.       return HXR_OK;
  242.    }
  243.     
  244.    return HXR_FAIL;
  245. }
  246. STDMETHODIMP_(ULONG32) CHXSiteStatusText::AddRef()
  247. {
  248.    return InterlockedIncrement(&m_lRefCount);
  249. }
  250. STDMETHODIMP_(ULONG32) CHXSiteStatusText::Release()
  251. {
  252.    if (InterlockedDecrement(&m_lRefCount) > 0)
  253.    {
  254.       return m_lRefCount;
  255.    }
  256.     
  257.    delete this;
  258.    return 0;
  259. }
  260. STDMETHODIMP CHXSiteStatusText::AttachSite(IHXSite* /*IN*/ pSite)
  261. {
  262.    HX_RESULT hr = HXR_FAIL;
  263.     
  264.    if (!m_pSite)
  265.    {
  266.       m_pSite = pSite;
  267.       m_pSite->AddRef();
  268.       hr = HXR_OK;
  269.    }
  270.     
  271.    return hr;
  272. }
  273. STDMETHODIMP CHXSiteStatusText::DetachSite()
  274. {
  275.    HX_RESULT hr = HXR_FAIL;
  276.     
  277.    if (m_pSite)
  278.    {
  279.       HX_RELEASE(m_pSite);
  280.       hr = HXR_OK;
  281.    }
  282.     
  283.    return hr;
  284. }
  285. STDMETHODIMP CHXSiteStatusText::HandleEvent(HXxEvent* /*IN*/ pEvent)
  286. {
  287.    HX_RESULT hr = HXR_OK;
  288.     
  289.    if (pEvent->event == HX_SURFACE_UPDATE)
  290.    {
  291.       _DrawStatusText(pEvent);
  292.    }
  293.     
  294.    return hr;
  295. }
  296. STDMETHODIMP_(BOOL) CHXSiteStatusText::NeedsWindowedSites()
  297. {
  298.    return false;
  299. }
  300. HX_RESULT CHXSiteStatusText::GetIHXSite2(REF(IHXSite2*) pSite2)
  301. {
  302.    HX_RESULT hr = HXR_FAIL;
  303.     
  304.    if (m_pSite)
  305.    {
  306.       hr = m_pSite->QueryInterface(IID_IHXSite2, (void**)&pSite2);
  307.    }
  308.     
  309.    return hr;
  310. }
  311. HX_RESULT CHXSiteStatusText::_DrawStatusText(HXxEvent* pEvent)
  312. {
  313.    HX_RESULT hr = HXR_OK;
  314.    HX_ASSERT(pEvent); 
  315.    int         direction;
  316.    int         ascent;
  317.    int         descent;
  318.    XCharStruct overall;
  319.    if (!m_pSite || m_statusSize.cx == 0)
  320.    {
  321.       return HXR_UNEXPECTED;
  322.    }
  323.    // if this is the first time in we should populate our data now
  324.    if (m_display == NULL)
  325.    {
  326.       // first get the site's window
  327.       IHXSiteWindowed* pSiteW = NULL;
  328.       HX_VERIFY(HXR_OK == m_pSite->QueryInterface(IID_IHXSiteWindowed, (void**)&pSiteW));
  329.       HXxWindow* pWindow  = pSiteW->GetWindow();
  330.       m_window = (Window) pWindow->window;
  331.       m_display = (Display*) pWindow->display;
  332.       int screenNumber = DefaultScreen(m_display);
  333.       m_colormap = DefaultColormap(m_display, screenNumber);
  334.       m_statusfont = XLoadQueryFont(m_display, "-adobe-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*");
  335.       HX_RELEASE(pSiteW);
  336.    }
  337.    // create the GC 
  338.    GC gc = XCreateGC(m_display, m_window, 0, 0);
  339.    // get the GC values we will need 
  340.    unsigned long mask = GCForeground | GCBackground | GCClipXOrigin | GCClipYOrigin;
  341.    XGCValues gcValues;
  342.    memset(&gcValues, 0, sizeof(XGCValues));
  343.    int r = XGetGCValues(m_display, gc, mask, &gcValues);
  344.    // save off the color pixel values
  345.    Pixel saveBG = gcValues.background;
  346.    Pixel saveFG = gcValues.foreground;
  347.    // convert color to Pixel values
  348.    XColor bgXColor, fgXColor;
  349.    ConvertRGBToXColor(m_rgbBkgndColor, bgXColor);
  350.    ConvertRGBToXColor(m_rgbTextColor, fgXColor);
  351.    // get color
  352.    if (!XAllocColor(m_display, m_colormap, &bgXColor))
  353.    {
  354.       // default to first color (is this really enough?)
  355.       bgXColor.pixel = 1;
  356.    }
  357.    if (!XAllocColor(m_display, m_colormap, &fgXColor))
  358.    {
  359.       // default to first color (is this really enough?)
  360.       fgXColor.pixel = 1;
  361.    }
  362.    // get the size of our region
  363.    HXxSize sz;
  364.    m_pSite->GetSize(sz);
  365.    // keep a local copy of status text in case we need to add an elipsis
  366.    CHXString statusText = m_StatusText;
  367.    int nStrLen = statusText.GetLength();
  368.    char* pStr = statusText.GetBuffer(statusText.GetLength()+1);
  369.    // get size of elipsis
  370.    XTextExtents(m_statusfont, ELIPSIS, strlen(ELIPSIS), &direction, &ascent, &descent, &overall);
  371.    int nElipsisLen = (overall.lbearing + overall.rbearing);
  372.    XTextExtents(m_statusfont, pStr, nStrLen, &direction, &ascent, &descent, &overall);
  373.    int nWidth = (overall.lbearing + overall.rbearing);
  374.    while (nWidth > m_statusSize.cx - DEF_HORZ_GUTTER && nStrLen > 0)
  375.    {
  376.       nStrLen--;
  377.       XTextExtents(m_statusfont, pStr, nStrLen, &direction, &ascent, &descent, &overall);
  378.       nWidth = (overall.lbearing + overall.rbearing);
  379.    }
  380.    if (nStrLen < statusText.GetLength())
  381.    {
  382.       statusText = statusText.Left(nStrLen);
  383.       statusText += ELIPSIS;
  384.       nStrLen += ELIPSIS_LEN;
  385.    }
  386.     
  387.    int nHeight = (int)((double)DEF_TEXT_HEIGHT * POINTS_TO_PIXELS);
  388.    int nX = max(0, (m_statusSize.cx - nWidth) / 2);
  389.    int nY = ((int)((double)m_statusSize.cy / 2 + (double)DEF_TEXT_HEIGHT/ 2)) + m_statusPos.y;
  390.    // set our colors into the gc
  391.    XSetBackground(m_display, gc, fgXColor.pixel);
  392.    XSetForeground(m_display, gc, bgXColor.pixel);
  393.    // fill first then draw text
  394.    XFillRectangle(m_display, m_window, gc, 
  395.                   m_statusPos.x, 
  396.                   m_statusPos.y,
  397.                   m_statusSize.cx,
  398.                   m_statusSize.cy);
  399.    XSetBackground(m_display, gc, bgXColor.pixel);
  400.    XSetForeground(m_display, gc, fgXColor.pixel);
  401.    // draw string
  402.    XDrawImageString(m_display, m_window, gc, nX, nY, (const char*) statusText, statusText.GetLength());
  403.    // reset orig. colors
  404.    XSetBackground(m_display, gc, saveBG);
  405.    XSetForeground(m_display, gc, saveFG);
  406.    // clean up colors
  407.    unsigned long pixels[2];
  408.    pixels[0] = bgXColor.pixel;
  409.    pixels[1] = fgXColor.pixel;
  410.    XFreeColors(m_display, m_colormap, pixels, 2, 0);
  411.    // release GC
  412.    XFreeGC(m_display, gc);
  413.    return hr;
  414. }
  415. BOOL CHXSiteStatusText::ConvertRGBToXColor(HXxColor& hxxColor, XColor& xcolor)
  416. {
  417.    // assume starting with a new XColor
  418.    memset(&xcolor, 0, sizeof(XColor));
  419.     
  420.     // separate r,g and b
  421.    UINT16 t;
  422.    t = (hxxColor & 0x00ff0000) >> 16;
  423.    xcolor.blue   = t << 8;
  424.     
  425.    t = (hxxColor & 0x0000ff00) >> 8;
  426.    xcolor.green = t << 8;
  427.     
  428.    t = (hxxColor & 0x000000ff);
  429.    xcolor.red  = t << 8;
  430.     
  431.    //color.pixel = n;
  432.    xcolor.flags = DoRed | DoGreen | DoBlue;
  433.    return TRUE;
  434. }
  435. HX_RESULT CHXSiteStatusText::_AdjustPosition(HXxPoint* pParentPos, HXxSize* pParentSize)
  436. {
  437.    HX_RESULT hr = HXR_OK;
  438.    
  439.    // this function is called internally and these will never be null
  440.    HX_ASSERT(pParentPos && pParentSize);
  441.    // take the max width of the parent site
  442.    m_statusPos.x = 0;
  443.    m_statusSize.cx = pParentSize->cx;
  444.     
  445.    // take at most the bottom DEF_STAT_HEIGHT pixels of the parent site
  446.    m_statusPos.y = max(pParentSize->cy - DEF_STAT_HEIGHT, 0);
  447.    m_statusSize.cy = pParentSize->cy - m_statusPos.y;
  448.     
  449.    return hr;
  450. }