📄 unixroot.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 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
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (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.
*
* 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 ***** */
// for shared memory
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/utsname.h>
#include "hxcom.h"
#include "hxwintyp.h"
#include "hxvsurf.h"
#include "hxslist.h"
#include "colormap.h"
#include "hxprefs.h"
#include "hxtick.h"
#include "hxthread.h"
#include "basesite.h"
#include "unixroot.h"
#include "unixsite.h"
#include "unixcmap.h"
#include "shmhelp.h"
// #ifdef _DEBUG
// #include <X11/extensions/xf86vmode.h> //for debug video sync rates..
// #endif
//Work around AIX problem.
#ifdef _AIX
# define MAX_SHARED_REGIONS ((UINT32)1)
#else
# define MAX_SHARED_REGIONS ((UINT32)9999)
#endif
CUnixRootSurf::CUnixRootSurf(IUnknown* pContext, CHXBaseSite* pSite )
: CBaseRootSurface(pContext, pSite)
, m_bUseShm(FALSE)
, m_nShmId(0)
, m_pDisplay(NULL)
, m_GC(0)
, m_nScreenNumber(0)
, m_pXImage(NULL)
, m_pVisual(NULL)
, m_unDepth(0)
, m_pScreen(NULL)
, m_pYUVScratchBits(NULL)
, m_nYUVScratchPitch(0)
, m_pScratchBits(NULL)
, m_nScratchPitch(0)
, m_nBitsPerPixel(0)
, m_nCompositionSize(0)
{
}
HX_RESULT CUnixRootSurf::Init()
{
//get window and display from main Site.
HXxWindow* pWindow = m_pSite->GetWindow();
HX_ASSERT(pWindow);
m_pDisplay = (Display*)pWindow->display;
m_window = (Window)pWindow->window;
HX_ASSERT( m_pDisplay );
HX_ASSERT( m_window );
//
// Now see if our X11 server supports the Shared Memory extension.
//
ShmHelp::Init(m_pDisplay);
m_bUseShm = ShmHelp::ShmAvailable();
//Create the graphics context
XGCValues values;
m_GC = XCreateGC(m_pDisplay, m_window, 0, &values);
//Get X window attributes & visual
XWindowAttributes attr;
XGetWindowAttributes(m_pDisplay, m_window, &attr);
m_pVisual = attr.visual;
// get visual info & depth
int nv=0;
XVisualInfo visInfo;
memset(&visInfo, 0, sizeof(XVisualInfo));
visInfo.visualid = XVisualIDFromVisual(m_pVisual);
XVisualInfo* pVisualInfo = XGetVisualInfo (m_pDisplay, VisualIDMask, &visInfo, &nv);
m_unDepth = pVisualInfo->depth;
m_nScreenNumber = DefaultScreen(m_pDisplay);
m_pScreen = XScreenOfDisplay(m_pDisplay, m_nScreenNumber);
m_colormap = HXGetXColormap(m_pDisplay, m_window);
// get pixmap (blt) information for the best depth we can display
int i=0;
int nNum=0;
XPixmapFormatValues *pixmap_formats = XListPixmapFormats(m_pDisplay, &nNum);
if(pixmap_formats)
{
for (i=0 ; i<nNum; i++)
{
if (pixmap_formats[i].depth == m_unDepth)
{
m_nBitsPerPixel = pixmap_formats[i].bits_per_pixel;
}
}
XFree(pixmap_formats);
pixmap_formats = NULL;
}
memset(&m_bmiSave, 0, sizeof(HXBitmapInfo));
m_bmiSave.bmiHeader.biBitCount = m_nBitsPerPixel;
m_bmiSave.bmiHeader.biCompression = (m_unDepth==8 ? BI_RGB : BI_BITFIELDS);
m_bmiSave.un.dwBitMask[0] = pVisualInfo->red_mask;
m_bmiSave.un.dwBitMask[1] = pVisualInfo->green_mask;
m_bmiSave.un.dwBitMask[2] = pVisualInfo->blue_mask;
//Set primary surface CID.
m_nCompositionSurfaceCID = GetBitmapColor(&m_bmiSave);
XFree( pVisualInfo );
// #ifdef _DEBUG
// //Lets find out what Hsync and Vsync rates we have for this display.
// //Ripped from xvidtune.c
// XF86VidModeModeLine mode_line;
// int scrn=0;
// int dot_clock;
// double vsync_hz, HSyncRate,HTotal, VTotal, PixelClock;
// if(XF86VidModeGetModeLine(m_pDisplay, scrn, &dot_clock, &mode_line))
// {
// PixelClock=dot_clock;
// HTotal = mode_line.htotal;
// VTotal = mode_line.vtotal;
// HSyncRate = PixelClock*1000.0/HTotal;
// vsync_hz = HSyncRate/VTotal;
// fprintf( stderr, "This Display's Hsync rate is: %f and Vsync: %f\n",
// HSyncRate, vsync_hz );
// }
// #endif
return HXR_OK;
}
CUnixRootSurf::~CUnixRootSurf()
{
_DestroyCompositionSurface();
if( m_GC )
{
XFreeGC( m_pDisplay, m_GC );
m_GC=0;
}
if (m_pVisual)
{
/* PJG: don't have to free visuals */
m_pVisual = NULL;
}
if(m_bUseShm)
{
if( m_pCompositionSurface != NULL )
ShmHelp::DetachSharedRegion(&m_pCompositionSurface, &m_shmInfo);
}
else
{
HX_DELETE(m_pCompositionSurface);
m_nCompositionSize=0;
m_bCompositionSurfaceCreated=FALSE;
}
//XXXgfw any more clean up for these two?
HX_VECTOR_DELETE( m_pScratchBits );
HX_VECTOR_DELETE( m_pYUVScratchBits );
}
HX_RESULT CUnixRootSurf::_ResizeVideoBuffer( INT32 nSize)
{
HX_RESULT retVal=HXR_OK;
if(nSize <= m_nCompositionSize)
return retVal;
if(m_bUseShm)
{
if( m_pCompositionSurface != NULL )
retVal = ShmHelp::DetachSharedRegion(&m_pCompositionSurface, &m_shmInfo);
if( retVal==HXR_OK )
{
retVal = ShmHelp::CreateSharedRegion( nSize,
&m_pCompositionSurface,
&m_nShmId,
&m_shmInfo
);
}
if( retVal != HXR_OK )
{
m_bCompositionSurfaceCreated = FALSE;
m_nCompositionSize = 0;
m_bUseShm = FALSE;
}
else
{
//It all worked
m_nCompositionSize = nSize;
m_bCompositionSurfaceCreated = TRUE;
return retVal;
}
}
//We need to fall through here so that if the shared memory stuff
//above fails we can create it the old fashioned way.
if(m_pCompositionSurface == NULL)
{
m_pCompositionSurface = (UCHAR*) malloc(nSize);
}
else
{
m_pCompositionSurface = (UCHAR*) realloc(m_pCompositionSurface, nSize);
}
if( m_pCompositionSurface )
{
m_nCompositionSize = nSize;
}
else
{
HX_ASSERT("We can't alloc the composition surface." == NULL );
m_nCompositionSize = 0;
}
return retVal;
}
HX_RESULT CUnixRootSurf::_DebugBlt( UCHAR* pImageData, HXBitmapInfoHeader* pBitmapInfo,
HXxRect& rDestRect, HXxRect& rSrcRect)
{
HX_ASSERT( m_window );
HX_ASSERT( m_pDisplay );
HX_ASSERT( m_GC );
XSetForeground( m_pDisplay, m_GC, WhitePixel(m_pDisplay, 0 ));
XSetBackground( m_pDisplay, m_GC, BlackPixel(m_pDisplay, 0 ));
XSetLineAttributes(m_pDisplay, m_GC, 5, LineSolid, CapRound, JoinRound );
XSetForeground( m_pDisplay, m_GC, WhitePixel(m_pDisplay, 0) );
XFillRectangle( m_pDisplay, m_window, m_GC,
rDestRect.left, rDestRect.top,
rDestRect.right-rDestRect.left,
rDestRect.bottom-rDestRect.top
);
XDrawRectangle( m_pDisplay, m_window, m_GC,
rDestRect.left, rDestRect.top,
rDestRect.right-rDestRect.left,
rDestRect.bottom-rDestRect.top
);
return HXR_OK;
}
void CUnixRootSurf::_GetYUVScratchWidthHeight(UINT32* pWidth, UINT32* pHeight)
{
*pWidth = m_bmiYUVScratch.bmiHeader.biWidth;
*pHeight = m_bmiYUVScratch.bmiHeader.biHeight;
}
XImage* CUnixRootSurf::_GetCompositionSurfaceDrawable()
{
return m_pXImage;
}
//Not used except for XING.....
void CUnixRootSurf::_CreateYUVScratchSurface(UINT32 width, UINT32 height)
{
//Remove old bits....
HX_DELETE(m_pYUVScratchBits);
//Clear BitmapInfo struct....
memset(&m_bmiYUVScratch, 0, sizeof(HXBitmapInfo));
int nResult = MakeBitmap( &m_bmiYUVScratch,
sizeof(m_bmiYUVScratch),
CID_YUY2,
width,
height,
NULL,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -