📄 sitetext.cpp
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: sitetext.cpp,v 1.1.1.1.42.5 2004/09/17 23:05:21 nhart Exp $ * * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. * * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks. You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL. Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. * * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. * * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. * * Technology Compatibility Kit Test Suite(s) Location: * http://www.helixcommunity.org/content/tck * * Contributor(s): * * ***** END LICENSE BLOCK ***** */#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/Intrinsic.h>#include "hxcom.h"#include "hxtypes.h"#include "hxwintyp.h"#include "hxmap.h"#include "hxslist.h"#include "ihxpckts.h"#include "hxwin.h"#include "hxengin.h"#include "hxsite2.h"#include "chxxtype.h"#include "hxvctrl.h"#include "hxvsurf.h"#include "surface.h"#include "vidosurf.h"#include "chxpckts.h"#include "hxevent.h"#include "sitemgr.h"#include "sitetext.h"//#include "pnmm.h" ??#define DEF_TEXT_HEIGHT 12#define POINTS_TO_PIXELS 1.5#define DEF_TEXT_GUTTER 1.2#define DEF_STAT_HEIGHT (int)((double)DEF_TEXT_HEIGHT * POINTS_TO_PIXELS * DEF_TEXT_GUTTER)#define DEF_HORZ_GUTTER 4#define ELIPSIS "..."#define ELIPSIS_LEN 3#define DEFAULT_X_FONT "-adobe-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*"#define FALLBACK_X_FONT "variable"// fwd declarestypedef ULONG32 COLORTYPE;CHXSiteStatusText::CHXSiteStatusText() : m_lRefCount(0) , m_pSite(NULL) , m_pParentSite(NULL) , m_rgbBkgndColor(0x00008000) , m_rgbTextColor(0x0000FF00) , m_colormap(0) , m_display(0) , m_window(0) , m_statusfont(NULL){ memset(&m_statusPos, 0, sizeof(HXxPoint)); memset(&m_statusSize, 0, sizeof(HXxSize));}CHXSiteStatusText::~CHXSiteStatusText(){ Destroy(); // make sure we cleanup}HX_RESULT CHXSiteStatusText::Create(IHXSite* pSite){ IHXSite* pChildSite = NULL; HX_RESULT hr = HXR_FAIL; HX_ASSERT(pSite); HX_ASSERT(!m_pSite); // keep a ref while we use the parent site pSite->AddRef(); if (pSite->CreateChild(pChildSite) == HXR_OK) { if (pChildSite->AttachUser(this) == HXR_OK) { m_pParentSite = pSite; if (m_StatusText.IsEmpty()) { Hide(); // keep hidden until we have status text } else { Show(); } UpdatePosition(); hr = HXR_OK; } HX_RELEASE(pChildSite); } // release if we failed if (hr != HXR_OK) { HX_RELEASE(pSite); } return hr;}HX_RESULT CHXSiteStatusText::Destroy(){ if (m_pSite) { if (m_pParentSite) { m_pParentSite->DestroyChild(m_pSite); } // DetachUser will call DetachSite, which will release m_pSite m_pSite->DetachUser(); m_pSite == NULL; } HX_RELEASE(m_pParentSite); return HXR_OK;}HX_RESULT CHXSiteStatusText::Show(){ IHXSite2* pSite2 = NULL; if (GetIHXSite2(pSite2) == HXR_OK) { pSite2->ShowSite(TRUE); HX_RELEASE(pSite2); } BringToTop(); return HXR_OK;}HX_RESULT CHXSiteStatusText::Hide(){ IHXSite2* pSite2 = NULL; if (GetIHXSite2(pSite2) == HXR_OK) { pSite2->ShowSite(FALSE); HX_RELEASE(pSite2); } return HXR_OK;}HX_RESULT CHXSiteStatusText::ParentChangedSize(){ UpdatePosition(); return HXR_OK;}HX_RESULT CHXSiteStatusText::BringToTop(){ IHXSite2* pSite2 = NULL; if (GetIHXSite2(pSite2) == HXR_OK) { pSite2->MoveSiteToTop(); HX_RELEASE(pSite2); } return HXR_OK;}HX_RESULT CHXSiteStatusText::UpdatePosition(){ HXxPoint parentPos; HXxSize parentSize; HX_RESULT res = HXR_FAIL; if (m_pParentSite && m_pSite) { if (m_pParentSite->GetSize(parentSize) == HXR_OK && m_pParentSite->GetPosition(parentPos) == HXR_OK) { // call platform-specific code to adjust the position & size // of our site (since fonts may require different heights on // different platforms _AdjustPosition(&parentPos, &parentSize); m_pSite->SetPosition(m_statusPos); m_pSite->SetSize(m_statusSize); if (!m_StatusText.IsEmpty()) { BringToTop(); } res = HXR_OK; } } return res;}void CHXSiteStatusText::SetStatusText(const char* pText){ m_StatusText = pText; if (m_StatusText.IsEmpty()) { Hide(); } else { Show(); }}STDMETHODIMP CHXSiteStatusText::QueryInterface(REFIID riid, void** ppvObj){ if (riid == IID_IHXSiteUser) { *ppvObj = (IHXSiteUser*)this; AddRef(); return HXR_OK; } if (riid == IID_IHXSiteWatcher) { *ppvObj = (IHXSiteWatcher*)this; AddRef(); return HXR_OK; } else if (riid == IID_IUnknown) { *ppvObj = (IUnknown*)(IHXSiteUser*)this; AddRef(); return HXR_OK; } return HXR_FAIL;}STDMETHODIMP_(ULONG32) CHXSiteStatusText::AddRef(){ return InterlockedIncrement(&m_lRefCount);}STDMETHODIMP_(ULONG32) CHXSiteStatusText::Release(){ if (InterlockedDecrement(&m_lRefCount) > 0) { return m_lRefCount; } delete this; return 0;}STDMETHODIMP CHXSiteStatusText::AttachSite(IHXSite* /*IN*/ pSite){ HX_RESULT hr = HXR_FAIL; if (!m_pSite) { m_pSite = pSite; m_pSite->AddRef(); hr = HXR_OK; } return hr;}STDMETHODIMP CHXSiteStatusText::DetachSite(){ HX_RESULT hr = HXR_FAIL; if (m_pSite) { HX_RELEASE(m_pSite); hr = HXR_OK; } return hr;}STDMETHODIMP CHXSiteStatusText::HandleEvent(HXxEvent* /*IN*/ pEvent){ HX_RESULT hr = HXR_OK; if (pEvent->event == HX_SURFACE_UPDATE) { _DrawStatusText(pEvent); } pEvent->handled = TRUE; pEvent->result = hr; return hr;}STDMETHODIMP_(BOOL) CHXSiteStatusText::NeedsWindowedSites(){ return false;}HX_RESULT CHXSiteStatusText::GetIHXSite2(REF(IHXSite2*) pSite2){ HX_RESULT hr = HXR_FAIL; if (m_pSite) { hr = m_pSite->QueryInterface(IID_IHXSite2, (void**)&pSite2); } return hr;}HX_RESULT CHXSiteStatusText::_DrawStatusText(HXxEvent* pEvent){ HX_RESULT hr = HXR_OK; HX_ASSERT(pEvent); int direction; int ascent; int descent; XCharStruct overall; if (!m_pSite || m_statusSize.cx == 0) { return HXR_UNEXPECTED; } // if this is the first time in we should populate our data now if (m_display == NULL) { // first get the site's window IHXSiteWindowed* pSiteW = NULL; HX_VERIFY(HXR_OK == m_pSite->QueryInterface(IID_IHXSiteWindowed, (void**)&pSiteW)); HXxWindow* pWindow = pSiteW->GetWindow(); m_window = (Window) pWindow->window; m_display = (Display*) pWindow->display; XLockDisplay(m_display); int screenNumber = DefaultScreen(m_display); m_colormap = DefaultColormap(m_display, screenNumber); m_statusfont = XLoadQueryFont(m_display, DEFAULT_X_FONT); if (!m_statusfont) { m_statusfont = XLoadQueryFont(m_display, FALLBACK_X_FONT); } XUnlockDisplay(m_display); HX_RELEASE(pSiteW); } // If we couldn't find a font to use then abort. if (!m_statusfont) { return HXR_FAIL; } // create the GC XLockDisplay(m_display); GC gc = XCreateGC(m_display, m_window, 0, 0); XUnlockDisplay(m_display); // get the GC values we will need unsigned long mask = GCForeground | GCBackground | GCClipXOrigin | GCClipYOrigin; XGCValues gcValues; memset(&gcValues, 0, sizeof(XGCValues)); XLockDisplay(m_display); int r = XGetGCValues(m_display, gc, mask, &gcValues); XUnlockDisplay(m_display); // save off the color pixel values Pixel saveBG = gcValues.background; Pixel saveFG = gcValues.foreground; // convert color to Pixel values XColor bgXColor, fgXColor; ConvertRGBToXColor(m_rgbBkgndColor, bgXColor); ConvertRGBToXColor(m_rgbTextColor, fgXColor); // get color XLockDisplay(m_display); int status1 = XAllocColor(m_display, m_colormap, &bgXColor); XUnlockDisplay(m_display); if (!status1) { // default to first color (is this really enough?) bgXColor.pixel = 1; } XLockDisplay(m_display); int status2 = XAllocColor(m_display, m_colormap, &fgXColor); XUnlockDisplay(m_display); if (!status2) { // default to first color (is this really enough?) fgXColor.pixel = 1; } // get the size of our region HXxSize sz; m_pSite->GetSize(sz); // keep a local copy of status text in case we need to add an elipsis CHXString statusText = m_StatusText; int nStrLen = statusText.GetLength(); char* pStr = statusText.GetBuffer(statusText.GetLength()+1); // get size of elipsis XTextExtents(m_statusfont, ELIPSIS, strlen(ELIPSIS), &direction, &ascent, &descent, &overall); int nElipsisLen = (overall.lbearing + overall.rbearing); XTextExtents(m_statusfont, pStr, nStrLen, &direction, &ascent, &descent, &overall); int nWidth = (overall.lbearing + overall.rbearing); while (nWidth > m_statusSize.cx - DEF_HORZ_GUTTER && nStrLen > 0) { nStrLen--; XTextExtents(m_statusfont, pStr, nStrLen, &direction, &ascent, &descent, &overall); nWidth = (overall.lbearing + overall.rbearing); } if (nStrLen < statusText.GetLength()) { statusText = statusText.Left(nStrLen); statusText += ELIPSIS; nStrLen += ELIPSIS_LEN; } int nHeight = (int)((double)DEF_TEXT_HEIGHT * POINTS_TO_PIXELS); int nX = max(0, (m_statusSize.cx - nWidth) / 2); int nY = ((int)((double)m_statusSize.cy / 2 + (double)DEF_TEXT_HEIGHT/ 2)) + m_statusPos.y; // set our colors into the gc XLockDisplay(m_display); XSetBackground(m_display, gc, fgXColor.pixel); XSetForeground(m_display, gc, bgXColor.pixel); // fill first then draw text XFillRectangle(m_display, m_window, gc, m_statusPos.x, m_statusPos.y, m_statusSize.cx, m_statusSize.cy); XSetBackground(m_display, gc, bgXColor.pixel); XSetForeground(m_display, gc, fgXColor.pixel); // draw string XDrawImageString(m_display, m_window, gc, nX, nY, (const char*) statusText, statusText.GetLength()); // reset orig. colors XSetBackground(m_display, gc, saveBG); XSetForeground(m_display, gc, saveFG); // clean up colors unsigned long pixels[2]; pixels[0] = bgXColor.pixel; pixels[1] = fgXColor.pixel; XFreeColors(m_display, m_colormap, pixels, 2, 0); // release GC XFreeGC(m_display, gc); XUnlockDisplay(m_display); return hr;}BOOL CHXSiteStatusText::ConvertRGBToXColor(HXxColor& hxxColor, XColor& xcolor){ // assume starting with a new XColor memset(&xcolor, 0, sizeof(XColor)); // separate r,g and b UINT16 t; t = (hxxColor & 0x00ff0000) >> 16; xcolor.blue = t << 8; t = (hxxColor & 0x0000ff00) >> 8; xcolor.green = t << 8; t = (hxxColor & 0x000000ff); xcolor.red = t << 8; //color.pixel = n; xcolor.flags = DoRed | DoGreen | DoBlue; return TRUE;}HX_RESULT CHXSiteStatusText::_AdjustPosition(HXxPoint* pParentPos, HXxSize* pParentSize){ HX_RESULT hr = HXR_OK; // this function is called internally and these will never be null HX_ASSERT(pParentPos && pParentSize); // take the max width of the parent site m_statusPos.x = 0; m_statusSize.cx = pParentSize->cx; // take at most the bottom DEF_STAT_HEIGHT pixels of the parent site m_statusPos.y = max(pParentSize->cy - DEF_STAT_HEIGHT, 0); m_statusSize.cy = pParentSize->cy - m_statusPos.y; return hr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -