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

Symbian

开发平台:

Visual C++

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