unixsurf.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:36k
- /* ***** BEGIN LICENSE BLOCK *****
- * Source last modified: $Id: unixsurf.cpp,v 1.2.40.5 2004/07/20 23:43:41 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 <errno.h>
- #include "hxcom.h"
- #include "hxtypes.h"
- #include "hxwintyp.h"
- #include "hxvsurf.h"
- #include "hxslist.h"
- #include "hxheap.h"
- #include "hxtick.h"
- #include "colormap.h"
- #include "hxthread.h"
- #include "ihxpckts.h"
- #include "unixsurf.h"
- #include "unixroot.h"
- #include "unixsite.h"
- #include "basesite.h"
- #include "shmhelp.h"
- #if defined(_LINUX) && defined(_OVERLAY)
- #include "hxprefs.h"
- CUnixSurf* CUnixSurf::zm_pXvOwner = NULL;
- #endif
- CUnixSurf::CUnixSurf( IUnknown* pContext, CHXBaseSite* pSite )
- : CBaseSurface( pContext, pSite )
- #if defined(_LINUX) && defined(_OVERLAY)
- , m_bWallPaperMode(FALSE)
- , m_nPortID(-1)
- , m_bPaintClipList(TRUE)
- , m_ulColorKey(0x01020304)
- , m_bStretchToFill(FALSE)
- , m_pXvImage(NULL)
- , m_atomColorKey(None)
- , m_atomClipKey(None)
- #if defined(HELIX_FEATURE_HARDWARE_COLOR_CONTROLS)
- , m_atomBrightness(None)
- , m_atomContrast(None)
- , m_atomHue(None)
- , m_atomSaturation(None)
- , m_nCurrBrightness(0)
- , m_nCurrContrast(0)
- , m_nCurrHue(0)
- , m_nCurrSaturation(0)
- #endif
- , m_ulLastOverlayUpdateTime(0)
- #endif
- , m_pcVideoBuf(NULL)
- , m_ulFourCCID(0)
- , m_nVideoPitch(0)
- , m_bUseShm(FALSE)
- , m_display(NULL)
- , m_GC(0)
- , m_nScreenNumber(0)
- , m_shmInfo(NULL)
- , m_nShmId(NULL)
- , m_nCurrentBuffer(0)
- , m_nCompletionEventID(-1)
- , m_nMultiBufferCount(2)
- {
- int i=0;
-
- #if defined(_LINUX) && defined(_OVERLAY)
- HX_ASSERT( m_pContext );
- IHXPreferences* pPreferences = NULL;
- if( m_pContext && HXR_OK == m_pContext->QueryInterface( IID_IHXPreferences, (void **) &pPreferences))
- {
- IHXBuffer *pBuffer = NULL;
- //This makes the overlay appear on the root window....
- //Just for inhouse testing right now...
- pPreferences->ReadPref("OverlayMode", pBuffer);
- if(pBuffer)
- {
- m_bUseOverlays = (::atoi((const char*)pBuffer->GetBuffer()) == 1);
- HX_RELEASE(pBuffer);
- }
- else
- {
- if (pPreferences->ReadPref("UseOverlay", pBuffer) == HXR_OK)
- {
- m_bUseOverlays = ::atoi((char*) pBuffer->GetBuffer()) == 1;
- }
- HX_RELEASE(pBuffer);
- }
- //This makes the overlay appear on the root window....
- //Just for inhouse testing right now...
- pPreferences->ReadPref("WallPaperMode", pBuffer);
- if (pBuffer)
- {
- m_bWallPaperMode = (::atoi((const char*)pBuffer->GetBuffer()) == 1);
- HX_RELEASE(pBuffer);
- }
- //This is used only when WallPaperMode=1 and stretches the
- //presentation to fill the whole root window NOT preserving
- //aspect ratio.
- pPreferences->ReadPref("StretchToFill", pBuffer);
- if (pBuffer)
- {
- m_bStretchToFill = (::atoi((const char*)pBuffer->GetBuffer()) == 1);
- HX_RELEASE(pBuffer);
- }
- //This is used on ATI cards for debugging. It tells the driver
- //to paint the window with the color key before each blt, or not.
- pPreferences->ReadPref("PaintClipList", pBuffer);
- if (pBuffer)
- {
- m_bPaintClipList = (::atoi((const char*)pBuffer->GetBuffer()) == 1);
- HX_RELEASE(pBuffer);
- }
- //This is the color key to use. If not set each card's driver will
- //choose one.
- pPreferences->ReadPref("ColorKey", pBuffer);
- if (pBuffer)
- {
- char *pszTmp = NULL;
- const char *pszColor = (const char*)pBuffer->GetBuffer();
- long lTmp = ::strtol(pszColor, &pszTmp, 0);
- HX_RELEASE(pBuffer);
- if( lTmp>=0 && pszTmp!=pszColor && errno!=ERANGE )
- {
- m_ulColorKey = lTmp;
- }
- }
- //Find out how much multi buffering to do
- m_nMultiBufferCount = 2; //default to 2.
- pPreferences->ReadPref("MultiBufferingCount", pBuffer);
- if (pBuffer)
- {
- char *pszTmp = NULL;
- const char *pszBufferCount = (const char*)pBuffer->GetBuffer();
- long lTmp = ::strtol(pszBufferCount, &pszTmp, 0);
- HX_RELEASE(pBuffer);
- if( pszTmp!=pszBufferCount && errno!=ERANGE )
- {
- m_nMultiBufferCount = lTmp;
- }
- }
- if( m_nMultiBufferCount < 1 )
- m_nMultiBufferCount = 1;
-
- HX_RELEASE( pPreferences );
- }
- if( m_bUseOverlays )
- {
- //Alloc our multi buffer lists.
- m_pXvImage = new XvImage* [m_nMultiBufferCount];
- m_pcVideoBuf = new UCHAR* [m_nMultiBufferCount];
- m_shmInfo = new XShmSegmentInfo[m_nMultiBufferCount];
- m_nShmId = new int[m_nMultiBufferCount];
- for( i=0 ; i<m_nMultiBufferCount ; i++ )
- {
- m_pXvImage[i] = NULL;
- m_pcVideoBuf[i] = NULL;
- m_nShmId[i] = -1;
- }
- }
-
- #endif //_LINUX && _OVERLAY
-
- }
- CUnixSurf::~CUnixSurf()
- {
- int i = 0;
-
- if( m_GC)
- {
- XLockDisplay(m_display);
- XFreeGC(m_display, m_GC);
- XUnlockDisplay(m_display);
- m_GC=0;
- }
-
- #if defined(_LINUX) && defined(_OVERLAY)
-
- if( m_pXvImage )
- {
- for( i=0; i<m_nMultiBufferCount; i++ )
- {
- XFree( m_pXvImage[i] );
- }
- HX_VECTOR_DELETE(m_pXvImage);
- }
-
- if( m_nPortID!=-1 )
- {
- XLockDisplay(m_display);
- XvUngrabPort( m_display, m_nPortID, CurrentTime );
- XUnlockDisplay(m_display);
- m_nPortID=-1;
- if( zm_pXvOwner==this )
- {
- zm_pXvOwner = NULL;
- }
- }
- if( m_pcVideoBuf != NULL )
- {
- for( i=0 ; i<m_nMultiBufferCount ; i++ )
- {
- if( m_nShmId[i] != -1 && m_bUseShm )
- {
- ShmHelp::DetachSharedRegion( &m_pcVideoBuf[i], &m_shmInfo[i] );
- m_nShmId[i] = -1;
- }
- else
- {
- HX_VECTOR_DELETE(m_pcVideoBuf[i]);
- }
- }
- HX_VECTOR_DELETE(m_pcVideoBuf);
- HX_VECTOR_DELETE(m_shmInfo);
- }
- memset( &m_surfaceSize, 0, sizeof(m_surfaceSize) );
-
- #endif //_LINUX && _OVERLAY
-
- }
- void CUnixSurf::_ReleaseSurface(CBaseRootSurface* pSurface)
- {
- //Release our grab on the port and assorted memory.....
- _ReleaseSurface();
- }
- void CUnixSurf::_DrawBlack(void* pWindow)
- {
- //XXXgfw fill whole window with black? Just our rect?
- }
- HX_RESULT CUnixSurf::_BltToPrimary(HXxRect& rDestRect, HXxRect& rSrcRect)
- {
- #ifdef _DEBUG
- fprintf( stderr, "CUnixSurf::_BltToPrimary is called...n" );
- #endif
- return HXR_FAIL;
- }
- void CUnixSurf::_CreateBuffer()
- {
- int i = 0;
- #if defined(_LINUX) && defined(_OVERLAY)
- //Clean up the old stuff....
- if( m_pcVideoBuf != NULL )
- {
- for( i=0 ; i<m_nMultiBufferCount ; i++ )
- {
- if( m_pcVideoBuf[i] != NULL )
- {
- if( m_nShmId[i] != -1 && m_bUseShm )
- {
- ShmHelp::DetachSharedRegion( &m_pcVideoBuf[i], &m_shmInfo[i] );
- m_nShmId[i] = -1;
- }
- else
- {
- HX_VECTOR_DELETE(m_pcVideoBuf[i]);
- }
- m_pcVideoBuf[i] = NULL;
- }
- }
- }
-
- if( m_pXvImage )
- {
- for( i=0; i<m_nMultiBufferCount; i++ )
- {
- if( m_pXvImage[i] != NULL )
- {
- XFree( m_pXvImage[i] );
- m_pXvImage[i] = NULL;
- }
- }
- }
- m_nVideoPitch = 0;
- HX_ASSERT( m_display );
- //Clear BitmapInfo struct....
- HXBitmapInfo bmi;
- memset( &bmi, 0, sizeof(HXBitmapInfo) );
- int nResult = MakeBitmap( &bmi,
- sizeof(bmi),
- m_nSurfaceCID,
- m_surfaceSize.cx,
- m_surfaceSize.cy,
- NULL,
- 0);
- if( nResult )
- {
- ShmHelp::Init(m_display);
- m_bUseShm = ShmHelp::ShmAvailable();
- for( i=0 ; i<m_nMultiBufferCount ; i++ )
- {
- if( m_bUseShm )
- {
- HX_RESULT retVal = ShmHelp::CreateSharedRegion( bmi.bmiHeader.biSizeImage,
- &m_pcVideoBuf[i],
- &m_nShmId[i],
- &m_shmInfo[i]
- );
- if( retVal != HXR_OK )
- {
- HX_ASSERT("Can't alloc shared memory segment." == NULL );
- m_nShmId[i] = -1;
- m_pcVideoBuf[i] = NULL;
- }
- }
-
- //did the shm alloc work?
- if( m_pcVideoBuf[i] == NULL )
- {
- m_bUseShm = FALSE;
- m_nShmId[i] = -1;
- m_pcVideoBuf[i] = new UCHAR[bmi.bmiHeader.biSizeImage];
- }
- HX_ASSERT( m_pcVideoBuf );
- }
- m_nVideoPitch = GetBitmapPitch(&bmi);
- }
-
- HX_ASSERT( m_nVideoPitch != 0 );
- //Now create the XvImage to blt to.....
- HX_ASSERT( m_nPortID != -1 );
- for( i=0 ; i<m_nMultiBufferCount ; i++ )
- {
- HX_ASSERT( m_pXvImage[i] == NULL );
- if( m_bUseShm )
- {
- XLockDisplay(m_display);
- m_pXvImage[i] = XvShmCreateImage( m_display,
- m_nPortID,
- m_ulFourCCID,
- (char*)m_pcVideoBuf[i],
- m_surfaceSize.cx,
- m_surfaceSize.cy,
- &m_shmInfo[i]
- );
- XUnlockDisplay(m_display);
- }
- else
- {
- XLockDisplay(m_display);
- m_pXvImage[i] = XvCreateImage( m_display,
- m_nPortID,
- m_ulFourCCID,
- (char*)m_pcVideoBuf[i],
- m_surfaceSize.cx,
- m_surfaceSize.cy
- );
- XUnlockDisplay(m_display);
- }
-
- if( m_pXvImage[i] == NULL )
- {
- HX_ASSERT("Could not create overlay surface"==NULL );
- //XXgfw, well, what to do here????
- }
- }
- if( m_bUseShm )
- {
- //Find the shm completion event ID.
- XLockDisplay(m_display);
- m_nCompletionEventID = XShmGetEventBase(m_display) + ShmCompletion;
- XUnlockDisplay(m_display);
- }
-
- #endif
- }
- BOOL CUnixSurf::_OverlayAvailable(int nFourCCWanted, int* pnPortID )
- {
- BOOL bRetVal = FALSE;
-
- #if defined(_LINUX) && defined(_OVERLAY)
- if( !m_bUseOverlays )
- {
- return bRetVal;
- }
-
- unsigned int nNumAdaptors = 0;
- int nImageCount = 0;
- int nPortID = -1;
- int i = 0;
- int j = 0;
- int k = 0;
- unsigned int ver = 0;
- unsigned int rel = 0;
- unsigned int req = 0;
- unsigned int ev = 0;
- unsigned int err = 0;
- int nRetCode = 0;
- XvImageFormatValues *pImageFormats = NULL;
- XvAdaptorInfo *pAdaptorInfo = NULL;
- //First, we need to map our cid to a FourCC.
- ULONG32 ulFourCC = 0;
- switch(nFourCCWanted)
- {
- case -1:
- //nothing requested
- break;
- case CID_I420:
- ulFourCC = MAKEFOURCC('I','4','2','0');
- break;
- case CID_YV12:
- ulFourCC = MAKEFOURCC('Y','V','1','2');
- break;
- case CID_YVU9:
- ulFourCC = MAKEFOURCC('Y','V','U','9');
- break;
- case CID_YUY2:
- ulFourCC = MAKEFOURCC('Y','U','Y','2');
- break;
- case CID_UYVY:
- ulFourCC = MAKEFOURCC('U','Y','V','Y');
- break;
- default:
- HX_ASSERT( "Unkown CID" == NULL );
- }
-
- if( m_pSite )
- {
- HX_ASSERT( m_pSite->GetWindow() );
- m_display = (Display*)((m_pSite->GetWindow())->display);
- }
- HX_ASSERT( m_display );
- //XXXgfw this code assumes that there is *only* one overlay available
- //on a machine. We need to change this as more become available....
- if( zm_pXvOwner != NULL )
- {
- //Someone owns the *one* overlay
- goto doneChecking;
- }
-
- XLockDisplay(m_display);
- nRetCode = XvQueryExtension(m_display, &ver, &rel, &req, &ev, &err);
- XUnlockDisplay(m_display);
- if( nRetCode != Success )
- {
- //Our X-Server doesn't support XVideo at all.
- bRetVal = FALSE;
- goto doneChecking;
- }
- XLockDisplay(m_display);
- nRetCode = XvQueryAdaptors( m_display,
- DefaultRootWindow(m_display),
- &nNumAdaptors,
- &pAdaptorInfo );
- XUnlockDisplay(m_display);
- if( nRetCode == Success && nNumAdaptors ) // pjg/gfw geForceII returns 0 adaptors with garbage return pointer
- {
- for(i=0 ; i<nNumAdaptors ; i++)
- {
- if(pAdaptorInfo[i].type & XvImageMask)
- {
- if( ulFourCC==0 )
- {
- //User just wants to know if we have overlays at all.
- bRetVal = TRUE;
- goto doneChecking;
- }
- XLockDisplay(m_display);
- pImageFormats = XvListImageFormats(m_display, pAdaptorInfo[i].base_id, &nImageCount);
- XUnlockDisplay(m_display);
- for( j=0 ; j<nImageCount ; j++)
- {
- if(pImageFormats[j].id == ulFourCC)
- {
- for( k=0 ; k<pAdaptorInfo[i].num_ports; k++)
- {
- XLockDisplay(m_display);
- int nSuc = XvGrabPort(m_display, pAdaptorInfo[i].base_id+k, CurrentTime);
- XUnlockDisplay(m_display);
- if(Success == nSuc)
- {
- //XXXgfw later, when we see graphics cards under linux
- //that have more than one overlay available we will need
- //to update this code......
-
- //Hey! We found one!
- nPortID = pAdaptorInfo[i].base_id+k;
- XLockDisplay(m_display);
- XvUngrabPort(m_display,
- pAdaptorInfo[i].base_id+k,
- CurrentTime );
- XUnlockDisplay(m_display);
- break;
- }
- }
- }
- if(nPortID != -1)
- break;
- }
- XFree(pImageFormats);
- }
- if(nPortID != -1)
- break;
- }
- XvFreeAdaptorInfo(pAdaptorInfo);
-
- if( nPortID != -1 )
- {
- bRetVal = TRUE;
- if( NULL != pnPortID )
- *pnPortID = nPortID;
- m_ulFourCCID = ulFourCC;
- }
-
- // fprintf( stderr, "Found a port that supports %d(%p), it is %dn",
- // nFourCCWanted, (void*)ulFourCC,nPortID );
- }
- doneChecking:
- #endif
-
- return bRetVal;
- }
- HX_RESULT CUnixSurf::_GetCaps(UINT32 *pfSurfaceCaps)
- {
- *pfSurfaceCaps = 0;
- if( _OverlayAvailable() )
- {
- *pfSurfaceCaps |= HX_OVERLAY;
- }
-
- return HXR_OK;
- }
- HX_RESULT CUnixSurf::_CreateOverlay(BOOL bOverlay, int cid, int x, int y)
- {
- HX_RESULT retVal = HXR_FAIL;
- int nSuc = Success;
- // fprintf( stderr, "CUnixSurf::_CreateOverlay(%p): bOverlay:%d cid:%d x,y: %d %dn",
- // this, bOverlay, cid, x, y);
- if( x & 15 )
- {
- x = (x&~15)+16;
- }
- #if defined(_LINUX) && defined(_OVERLAY)
- if( bOverlay )
- {
- int nPortID = 0;
- BOOL bAvailable = FALSE;
- bAvailable = _OverlayAvailable( cid, &nPortID );
- if( bAvailable )
- {
- HX_ASSERT(m_display);
- //Grab the port.
- XLockDisplay(m_display);
- nSuc = XvGrabPort( m_display, nPortID, CurrentTime );
- XUnlockDisplay(m_display);
- if( nSuc == Success )
- {
- //Take ownership of the overlay. A connection to the XServer
- //can grab the overlay port as much as it wants so we can't
- //rely on that to make sure that we only have one surface
- //using the overlay.
- m_nPortID = nPortID;
- zm_pXvOwner = this;
-
- //So far so good. Now we need to grab all of our atoms to control
- //the overlay
- XLockDisplay(m_display);
- m_atomColorKey = XInternAtom(m_display, "XV_COLOR_KEY", True);
- XUnlockDisplay(m_display);
- if( m_atomColorKey == None )
- {
- //There isn't a naming convention for any of these atoms. we
- //have to disover at run time what they are.
- XLockDisplay(m_display);
- m_atomColorKey = XInternAtom(m_display, "XV_COLORKEY", True);
- XUnlockDisplay(m_display);
- }
- XLockDisplay(m_display);
- m_atomClipKey = XInternAtom(m_display, "XV_PAINT_CLIPLIST", True);
- XUnlockDisplay(m_display);
- //Now set some of the atoms we read from the prefs
- if( None != m_atomClipKey)
- {
- XLockDisplay(m_display);
- XvSetPortAttribute(m_display, m_nPortID, m_atomClipKey, m_bPaintClipList);
- XUnlockDisplay(m_display);
- }
- #if defined(HELIX_FEATURE_HARDWARE_COLOR_CONTROLS)
- XLockDisplay(m_display);
- m_atomBrightness = XInternAtom(m_display, "XV_BRIGHTNESS", True);
- m_atomContrast = XInternAtom(m_display, "XV_CONTRAST", True);
- m_atomHue = XInternAtom(m_display, "XV_HUE", True);
- m_atomSaturation = XInternAtom(m_display, "XV_SATURATION", True);
- //Get the min and max values for each settable atom.
- int nNumAttributes = 0;
- XvAttribute* pPAList = XvQueryPortAttributes( m_display,
- m_nPortID,
- &nNumAttributes );
- XUnlockDisplay(m_display);
- for( int nIdx=0; nIdx < nNumAttributes; nIdx++ )
- {
- const char* pszName = pPAList[nIdx].name;
- int nMin = pPAList[nIdx].min_value;
- int nMax = pPAList[nIdx].max_value;
-
- stPortAttribute paTmp(nMin, nMax);
-
- if( !strcmp(pszName, "XV_BRIGHTNESS" ))
- {
- XLockDisplay(m_display);
- XvGetPortAttribute( m_display, m_nPortID, m_atomBrightness, &m_nCurrBrightness );
- XUnlockDisplay(m_display);
- paBrightness = paTmp;
- }
- if( !strcmp(pszName, "XV_CONTRAST" ))
- {
- XLockDisplay(m_display);
- XvGetPortAttribute( m_display, m_nPortID, m_atomContrast, &m_nCurrContrast );
- XUnlockDisplay(m_display);
- paContrast = paTmp;
- }
- if( !strcmp(pszName, "XV_HUE" ))
- {
- XLockDisplay(m_display);
- XvGetPortAttribute( m_display, m_nPortID, m_atomHue, &m_nCurrHue );
- XUnlockDisplay(m_display);
- paHue = paTmp;
- }
- if( !strcmp(pszName, "XV_SATURATION" ))
- {
- XLockDisplay(m_display);
- XvGetPortAttribute( m_display, m_nPortID, m_atomSaturation, &m_nCurrSaturation );
- XUnlockDisplay(m_display);
- paSaturation = paTmp;
- }
- }
-
- if( pPAList )
- XFree( pPAList );
- #endif
- //Now we need to create the overlay surface???
- m_surfaceSize.cx = x;
- m_surfaceSize.cy = y;
- m_nSurfaceCID = cid;
- m_nBltMode = HX_OVERLAY_BLT;
- _CreateBuffer();
- //Return good.
- retVal = HXR_OK;
- }
- }
- } //if(bOverlay)...
- #endif
- return retVal;
- }
- HX_RESULT CUnixSurf::_LockInternalSurface( UCHAR** ppSurfPtr,
- LONG32* pnSurfPitch,
- HXxSize& notused )
- {
- HX_RESULT retVal = HXR_OK;
- //Flip internal buffers....
- m_nCurrentBuffer++;
- if( m_nCurrentBuffer >= m_nMultiBufferCount )
- {
- m_nCurrentBuffer=0;
- }
- HX_ASSERT( m_pcVideoBuf[m_nCurrentBuffer] );
- HX_ASSERT( m_nVideoPitch != 0 );
-
- *ppSurfPtr = (UCHAR*)m_pcVideoBuf[m_nCurrentBuffer];
- *pnSurfPitch = m_nVideoPitch;
- return retVal;
- }
- HX_RESULT CUnixSurf::_UnlockInternalSurface(UCHAR* pSurfPtr)
- {
- return HXR_OK;
- }
- void CUnixSurf::_SetupDCObjects(HXxDC hxxDC, void** phOldBrush, void** phOldPen)
- {
- }
- void CUnixSurf::_FillRectangle(HXxDC hxxDC,
- UINT32 left, UINT32 top,
- UINT32 right, UINT32 bottom)
- {
- if( !hxxDC )
- return;
- // XXXNH: constrain ourselves to the current image size. When the site
- // is shrunk (eg: via user action) we can enter a situation where a
- // damaged rect is queued up for drawing that is larger than the current
- // image. We will crash if we don't constrain it to the current size.
- XImage* pImage = (XImage*)hxxDC;
- if (right > pImage->width)
- right = pImage->width;
- if (bottom > pImage->height)
- bottom = pImage->height;
- for( int x=left; x<=right-1; x++ )
- {
- for( int y=top; y<=bottom-1; y++ )
- {
- #if defined _LINUX && defined _OVERLAY
- XPutPixel( pImage, x, y, m_ulColorKey );
- #endif
- }
- }
- }
- void CUnixSurf::_RestoreDCObjects(HXxDC hxxDC, void* hOldBrush, void* hOldPen)
- {
- }
- void CUnixSurf::_GetCompositionSurfaceHXxDC(HXxDC *hdc)
- {
- //This needs to return a drawable that points to the composition surface...
- CUnixRootSurf* pSurface = (CUnixRootSurf*)m_pSite->GetRootSurface();
- XImage *pImage = pSurface->_GetCompositionSurfaceDrawable();
- *hdc = (HXxDC)pImage;
- }
- void CUnixSurf::_ReleaseCompositionSurfaceHXxDC(HXxDC hdc)
- {
- //Nothing to do on unix...
- }
- INT32 CUnixSurf::_InsureColorMatch(INT32 InColor)
- {
- return InColor;
- }
- void CUnixSurf::_SetColorKey(INT32 nColorSpaceLowValue,INT32 nColorSpaceHighValue)
- {
- #if defined(_LINUX) && defined(_OVERLAY)
- static BOOL bDoneItAlready = FALSE;
-
- if( m_atomColorKey != None && !bDoneItAlready)
- {
- if( m_ulColorKey == 0x01020304 )
- {
- m_ulColorKey = nColorSpaceHighValue;
- //The user did not set a color key preference...
- XLockDisplay(m_display);
- XvSetPortAttribute( m_display, m_nPortID, m_atomColorKey, nColorSpaceHighValue );
- XUnlockDisplay(m_display);
- }
- else
- {
- XLockDisplay(m_display);
- XvSetPortAttribute( m_display, m_nPortID, m_atomColorKey, m_ulColorKey );
- XUnlockDisplay(m_display);
- }
- bDoneItAlready = TRUE;
- }
- #endif
- }
- static BOOL CheckIt(Display* dis, XEvent* event, XPointer arg)
- {
- BOOL ret = (event->type==(int)arg);
- return ret;
- }
- #if defined(HELIX_FEATURE_HARDWARE_COLOR_CONTROLS)
- inline int _scaleIt( float v, stPortAttribute at )
- {
- int nRetVal = (int)(((v+1)*(at.nMaxValue-at.nMinValue))/2+at.nMinValue);
- if( nRetVal < at.nMinValue )
- nRetVal = at.nMinValue;
- if( nRetVal > at.nMaxValue )
- nRetVal = at.nMaxValue;
- }
- BOOL CUnixSurf::HasHWColorConrols()
- {
- BOOL retVal=FALSE;
- if( None != m_atomBrightness &&
- None != m_atomHue &&
- None != m_atomSaturation &&
- None != m_atomContrast )
- {
- retVal = TRUE;
- }
- return retVal;
- }
- void CUnixSurf::SetHWColorControls()
- {
- float fBright = m_pSite->GetBrightness();
- float fContrast = m_pSite->GetContrast();
- float fHue = m_pSite->GetHue();
- float fSaturation = m_pSite->GetSaturation();
- if( None != m_atomBrightness )
- {
- int nVal = _scaleIt( fBright, paBrightness);
- if( nVal != m_nCurrBrightness )
- {
- XLockDisplay(m_display);
- XvSetPortAttribute(m_display, m_nPortID, m_atomBrightness, nVal);
- XUnlockDisplay(m_display);
- m_nCurrBrightness = nVal;
- }
- }
- if( None != m_atomContrast)
- {
- int nVal = _scaleIt( fContrast, paContrast);
- if( nVal != m_nCurrContrast )
- {
- XLockDisplay(m_display);
- XvSetPortAttribute(m_display, m_nPortID, m_atomContrast, nVal);
- XUnlockDisplay(m_display);
- m_nCurrContrast = nVal;
- }
- }
- if( None != m_atomHue)
- {
- int nVal = _scaleIt( fHue, paHue);
- if( nVal != m_nCurrHue )
- {
- XLockDisplay(m_display);
- XvSetPortAttribute(m_display, m_nPortID, m_atomHue, nVal);
- XUnlockDisplay(m_display);
- m_nCurrHue = nVal;
- }
- }
- if( None != m_atomSaturation)
- {
- int nVal = _scaleIt( fSaturation, paSaturation);
- if( nVal != m_nCurrSaturation )
- {
- XLockDisplay(m_display);
- XvSetPortAttribute(m_display, m_nPortID, m_atomSaturation, nVal);
- XUnlockDisplay(m_display);
- m_nCurrSaturation = nVal;
- }
- }
- }
- #endif
- void CUnixSurf::_UpdateOverlay(HXxRect* dest, HXxRect* src, INT32 inFlags)
- {
- HXxWindow* pWin = m_pSite->GetWindow();
- CBaseRootSurface* pRootSurface = m_pSite->GetRootSurface();
- int nRet = 0;
- Window winSurface = 0;
- HXxRect rectDest = {0,0,0,0};
- memcpy( &rectDest, dest, sizeof( HXxRect ) ); /* Flawfinder: ignore */
- HX_ASSERT( m_nMultiBufferCount );
- #if defined(_LINUX) && defined(_OVERLAY)
- m_ulLastOverlayUpdateTime = HX_GET_TICKCOUNT();
-
- //Draw on the root window if the user wants it. This feature isn't tested
- //and has known problems for certain window managers that create their own
- //window over the root. Looks really cool when it works though. :) Turn
- //this on set the color key to the background color of all your xterms.
- //Very nice.
- if( !m_bWallPaperMode )
- {
- winSurface = (Window)pWin->window;
- }
- else
- {
- winSurface = DefaultRootWindow(m_display);
- }
-
- HX_ASSERT( pWin );
- #ifdef _DEBUG
- // static ULONG32 ulLast =0;
- // static ULONG32 ulCount =0;
- // static ULONG32 ulCountTot =0;
- // static double fpsTot=0;
- // ULONG32 ulCurr = HX_GET_TICKCOUNT();
- // if( ulCurr-ulLast>1000 )
- // {
- // float fps = (float)ulCount/((float)(ulCurr-ulLast)/1000.0);
- // fpsTot += fps;
- // ulCountTot++;
-
- // fprintf( stderr, "%lu elapsed microseconds. %lu frames. %f FPS (Ave: %f)n",
- // ulCurr-ulLast, ulCount, fps, fpsTot/(double)ulCountTot );
- // ulCount = 0;
- // ulLast = ulCurr;
- // }
- // ulCount++;
- #endif
- //if we are on the root window, calculate new dest rect.
- //Copy the one passed in.
- if( m_bWallPaperMode )
- {
- XLockDisplay(m_display);
- Screen* pScreen = XDefaultScreenOfDisplay(m_display);
- XUnlockDisplay(m_display);
- UINT16 uHorzRes = WidthOfScreen(pScreen);
- UINT16 uVertRes = HeightOfScreen(pScreen);
- //if the user wants to stretchtofill then make the dest rect the
- //whole screen, otherwise preserve aspec ration.
- if( m_bStretchToFill )
- {
- //Make it the whole screen.
- rectDest.left = 0;
- rectDest.top = 0;
- rectDest.right = uHorzRes;
- rectDest.bottom = uVertRes;
- }
- else
- {
- //maintain aspect ration.
- //Scale it.
- float fXScale = (float)uHorzRes/(float)(dest->right-dest->left);
- float fYScale = (float)uVertRes/(float)(dest->bottom-dest->top);
- float fScale = (fXScale<fYScale) ? fXScale : fYScale;
- int nWidth = (int)(fScale*(dest->right-dest->left)+.5);
- int nHeight = (int)(fScale*(dest->bottom-dest->top)+.5);
- rectDest.left = 0;
- rectDest.top = 0;
-
- if( nWidth<uHorzRes )
- rectDest.left = (uHorzRes-nWidth)/2;
- if( nHeight<uVertRes )
- rectDest.top = (uVertRes-nHeight)/2;
- rectDest.right = rectDest.left+nWidth;
- rectDest.bottom = rectDest.top+nHeight;
- }
- }
- if( m_bUseShm )
- {
- XLockDisplay(m_display);
- nRet = XvShmPutImage( m_display,
- m_nPortID,
- winSurface,
- ((CUnixRootSurf*)pRootSurface)->GetGC(),
- m_pXvImage[m_nCurrentBuffer],
- src->left,
- src->top,
- src->right - src->left,
- src->bottom - src->top,
- rectDest.left,
- rectDest.top,
- rectDest.right - rectDest.left,
- rectDest.bottom - rectDest.top,
- True
- );
- XUnlockDisplay(m_display);
- }
- else
- {
- XLockDisplay(m_display);
- nRet = XvPutImage( m_display,
- m_nPortID,
- winSurface,
- ((CUnixRootSurf*)pRootSurface)->GetGC(),
- m_pXvImage[m_nCurrentBuffer],
- src->left,
- src->top,
- src->right - src->left,
- src->bottom - src->top,
- rectDest.left,
- rectDest.top,
- rectDest.right - rectDest.left,
- rectDest.bottom - rectDest.top
- );
- XUnlockDisplay(m_display);
- }
- if( m_bUseShm && m_nMultiBufferCount==1 )
- {
- //If we aren't at least double buffering and we are using
- //shared memory, make sure we wait for the completion of the
- //copy of the shared memory segment to the server. Tear not
- //want not.
- HX_ASSERT( m_nCompletionEventID > 0 );
- XEvent event;
- XLockDisplay(m_display);
- XIfEvent( m_display, &event, CheckIt, (XPointer)m_nCompletionEventID );
- XUnlockDisplay(m_display);
- }
-
- #endif
- }
- BOOL CUnixSurf::_IsSurfaceVisible()
- {
- return TRUE;
- }
- void CUnixSurf::_ReleaseSurface()
- {
- int i=0;
-
- #if defined(_LINUX) && defined(_OVERLAY)
- //Release all of our overlay resources.....
- if( m_nPortID!=-1 )
- {
- XLockDisplay(m_display);
- XvUngrabPort( m_display, m_nPortID, CurrentTime );
- XUnlockDisplay(m_display);
- m_nPortID=-1;
- if( zm_pXvOwner==this )
- {
- zm_pXvOwner = NULL;
- }
- }
- if( m_pcVideoBuf != NULL )
- {
- for( i=0 ; i<m_nMultiBufferCount ; i++ )
- {
- if( m_nShmId[i] != -1 && m_bUseShm )
- {
- ShmHelp::DetachSharedRegion( &m_pcVideoBuf[i], &m_shmInfo[i] );
- m_nShmId[i] = -1;
- }
- else
- {
- HX_VECTOR_DELETE(m_pcVideoBuf[i]);
- }
- m_pcVideoBuf[i] = NULL;
- }
- }
-
- if( m_pXvImage )
- {
- for( i=0; i<m_nMultiBufferCount; i++ )
- {
- XFree( m_pXvImage[i] );
- m_pXvImage[i] = NULL;
- }
- }
- memset( &m_surfaceSize, 0, sizeof(m_surfaceSize) );
- m_nSurfaceCID = 1234; //what else?
- #endif
- }
- HXxDC CUnixSurf::_GetDC(HXxWindow*)
- {
- return (HXxDC)m_GC;
- }
- void CUnixSurf::_ReleaseDC(HXxWindow*, HXxDC)
- {
- }
- void CUnixSurf::_GetWindowDeviceCords(HXxRect* rect )
- {
- memset( rect, 0, sizeof( HXxRect) );
- }