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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: unixsurf.cpp,v 1.2.40.5 2004/07/20 23:43:41 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 <errno.h>
  50. #include "hxcom.h"
  51. #include "hxtypes.h"
  52. #include "hxwintyp.h"
  53. #include "hxvsurf.h"
  54. #include "hxslist.h"
  55. #include "hxheap.h"
  56. #include "hxtick.h"
  57. #include "colormap.h"
  58. #include "hxthread.h"
  59. #include "ihxpckts.h"
  60. #include "unixsurf.h"
  61. #include "unixroot.h"
  62. #include "unixsite.h"
  63. #include "basesite.h"
  64. #include "shmhelp.h"
  65. #if defined(_LINUX) && defined(_OVERLAY)
  66. #include "hxprefs.h"
  67. CUnixSurf* CUnixSurf::zm_pXvOwner     = NULL;
  68. #endif
  69. CUnixSurf::CUnixSurf( IUnknown* pContext, CHXBaseSite* pSite )
  70.     : CBaseSurface( pContext, pSite )
  71. #if defined(_LINUX) && defined(_OVERLAY)
  72.     , m_bWallPaperMode(FALSE)
  73.     , m_nPortID(-1)
  74.     , m_bPaintClipList(TRUE)
  75.     , m_ulColorKey(0x01020304)
  76.     , m_bStretchToFill(FALSE)
  77.     , m_pXvImage(NULL)
  78.     , m_atomColorKey(None)
  79.     , m_atomClipKey(None)
  80. #if defined(HELIX_FEATURE_HARDWARE_COLOR_CONTROLS)
  81.     , m_atomBrightness(None)
  82.     , m_atomContrast(None)
  83.     , m_atomHue(None)
  84.     , m_atomSaturation(None)
  85.     , m_nCurrBrightness(0)
  86.     , m_nCurrContrast(0)
  87.     , m_nCurrHue(0)
  88.     , m_nCurrSaturation(0)
  89. #endif    
  90.     , m_ulLastOverlayUpdateTime(0)
  91. #endif
  92.     , m_pcVideoBuf(NULL)
  93.     , m_ulFourCCID(0)
  94.     , m_nVideoPitch(0)
  95.     , m_bUseShm(FALSE)
  96.     , m_display(NULL)
  97.     , m_GC(0)
  98.     , m_nScreenNumber(0)
  99.     , m_shmInfo(NULL)
  100.     , m_nShmId(NULL)
  101.     , m_nCurrentBuffer(0)
  102.     , m_nCompletionEventID(-1)
  103.     , m_nMultiBufferCount(2)
  104. {
  105.     int i=0;
  106.     
  107. #if defined(_LINUX) && defined(_OVERLAY)
  108.     HX_ASSERT( m_pContext );
  109.     IHXPreferences* pPreferences = NULL;   
  110.     if( m_pContext && HXR_OK == m_pContext->QueryInterface( IID_IHXPreferences, (void **) &pPreferences))
  111.     { 
  112.         IHXBuffer *pBuffer = NULL;
  113.         //This makes the overlay appear on the root window....
  114.         //Just for inhouse testing right now...
  115.         pPreferences->ReadPref("OverlayMode", pBuffer);
  116.         if(pBuffer)
  117.         {
  118.             m_bUseOverlays = (::atoi((const char*)pBuffer->GetBuffer()) == 1);
  119.             HX_RELEASE(pBuffer);
  120.         }
  121.         else
  122.         {
  123.             if (pPreferences->ReadPref("UseOverlay", pBuffer) == HXR_OK)
  124.             {
  125.                 m_bUseOverlays = ::atoi((char*) pBuffer->GetBuffer()) == 1;
  126.             }
  127.             HX_RELEASE(pBuffer);
  128.         }
  129.         //This makes the overlay appear on the root window....
  130.         //Just for inhouse testing right now...
  131.         pPreferences->ReadPref("WallPaperMode", pBuffer);
  132.         if (pBuffer)
  133.         {
  134.             m_bWallPaperMode = (::atoi((const char*)pBuffer->GetBuffer()) == 1);
  135.             HX_RELEASE(pBuffer);
  136.         }
  137.         //This is used only when WallPaperMode=1 and stretches the
  138.         //presentation to fill the whole root window NOT preserving
  139.         //aspect ratio.
  140.         pPreferences->ReadPref("StretchToFill", pBuffer);
  141.         if (pBuffer)
  142.         {
  143.             m_bStretchToFill = (::atoi((const char*)pBuffer->GetBuffer()) == 1);
  144.             HX_RELEASE(pBuffer);
  145.         }
  146.         //This is used on ATI cards for debugging. It tells the driver
  147.         //to paint the window with the color key before each blt, or not.
  148.         pPreferences->ReadPref("PaintClipList", pBuffer);
  149.         if (pBuffer)
  150.         {
  151.             m_bPaintClipList = (::atoi((const char*)pBuffer->GetBuffer()) == 1);
  152.             HX_RELEASE(pBuffer);
  153.         }
  154.         //This is the color key to use. If not set each card's driver will
  155.         //choose one.
  156.         pPreferences->ReadPref("ColorKey", pBuffer);
  157.         if (pBuffer)
  158.         {
  159.             char *pszTmp   = NULL;
  160.             const char *pszColor = (const char*)pBuffer->GetBuffer();
  161.             long lTmp = ::strtol(pszColor, &pszTmp, 0);
  162.             HX_RELEASE(pBuffer);
  163.             if( lTmp>=0 && pszTmp!=pszColor && errno!=ERANGE )
  164.             {
  165.                 m_ulColorKey = lTmp;
  166.             }
  167.         }
  168.         //Find out how much multi buffering to do
  169.         m_nMultiBufferCount = 2; //default to 2.
  170.         pPreferences->ReadPref("MultiBufferingCount", pBuffer);
  171.         if (pBuffer)
  172.         {
  173.             char *pszTmp   = NULL;
  174.             const char *pszBufferCount = (const char*)pBuffer->GetBuffer();
  175.             long lTmp = ::strtol(pszBufferCount, &pszTmp, 0);
  176.             HX_RELEASE(pBuffer);
  177.             if( pszTmp!=pszBufferCount && errno!=ERANGE )
  178.             {
  179.                 m_nMultiBufferCount = lTmp;
  180.             }
  181.         }
  182.         if( m_nMultiBufferCount < 1 )
  183.             m_nMultiBufferCount = 1;
  184.       
  185.         HX_RELEASE( pPreferences );
  186.     }
  187.     if( m_bUseOverlays )
  188.     {
  189.         //Alloc our multi buffer lists.
  190.         m_pXvImage   = new XvImage* [m_nMultiBufferCount];
  191.         m_pcVideoBuf = new UCHAR* [m_nMultiBufferCount];
  192.         m_shmInfo    = new XShmSegmentInfo[m_nMultiBufferCount];
  193.         m_nShmId     = new int[m_nMultiBufferCount];
  194.         for( i=0 ; i<m_nMultiBufferCount ; i++ )
  195.         {
  196.             m_pXvImage[i] = NULL;
  197.             m_pcVideoBuf[i] = NULL;
  198.             m_nShmId[i] = -1;
  199.         }
  200.     }
  201.    
  202. #endif //_LINUX && _OVERLAY
  203.    
  204. }
  205. CUnixSurf::~CUnixSurf()
  206. {
  207.     int i = 0;
  208.     
  209.     if( m_GC)
  210.     {
  211.         XLockDisplay(m_display);
  212.         XFreeGC(m_display, m_GC);
  213. XUnlockDisplay(m_display);
  214.         m_GC=0;
  215.     }
  216.     
  217. #if defined(_LINUX) && defined(_OVERLAY)
  218.    
  219.     if( m_pXvImage )
  220.     {
  221.         for( i=0; i<m_nMultiBufferCount; i++ )
  222.         {
  223.             XFree( m_pXvImage[i] );
  224.         }
  225.         HX_VECTOR_DELETE(m_pXvImage);
  226.     }
  227.    
  228.     if( m_nPortID!=-1 )
  229.     {
  230. XLockDisplay(m_display);
  231.         XvUngrabPort( m_display, m_nPortID, CurrentTime );
  232. XUnlockDisplay(m_display);
  233.         m_nPortID=-1;
  234.         if( zm_pXvOwner==this )
  235.         {
  236.             zm_pXvOwner = NULL;
  237.         }
  238.     }
  239.     if( m_pcVideoBuf != NULL )
  240.     {
  241.         for( i=0 ; i<m_nMultiBufferCount ; i++ )
  242.         {
  243.             if( m_nShmId[i] != -1 && m_bUseShm )
  244.             {
  245.                 ShmHelp::DetachSharedRegion( &m_pcVideoBuf[i], &m_shmInfo[i] );
  246.                 m_nShmId[i] = -1;
  247.             }
  248.             else
  249.             {
  250.                 HX_VECTOR_DELETE(m_pcVideoBuf[i]);
  251.             }
  252.         }
  253.         HX_VECTOR_DELETE(m_pcVideoBuf);
  254.         HX_VECTOR_DELETE(m_shmInfo);
  255.     }
  256.     memset( &m_surfaceSize, 0, sizeof(m_surfaceSize) );
  257.    
  258. #endif //_LINUX && _OVERLAY
  259.    
  260. }
  261. void CUnixSurf::_ReleaseSurface(CBaseRootSurface* pSurface)
  262. {
  263.     //Release our grab on the port and assorted memory.....
  264.     _ReleaseSurface();
  265. }
  266. void CUnixSurf::_DrawBlack(void* pWindow)
  267. {
  268.     //XXXgfw fill whole window with black? Just our rect?
  269. }
  270. HX_RESULT CUnixSurf::_BltToPrimary(HXxRect& rDestRect, HXxRect& rSrcRect)
  271. {
  272. #ifdef _DEBUG   
  273.     fprintf( stderr, "CUnixSurf::_BltToPrimary is called...n" );
  274. #endif   
  275.     return HXR_FAIL;
  276. }
  277. void CUnixSurf::_CreateBuffer()
  278. {
  279.     int i = 0;
  280. #if defined(_LINUX) && defined(_OVERLAY)
  281.     //Clean up the old stuff....
  282.     if( m_pcVideoBuf != NULL )
  283.     {
  284.         for( i=0 ; i<m_nMultiBufferCount ; i++ )
  285.         {
  286.             if( m_pcVideoBuf[i] != NULL )
  287.             {
  288.                 if( m_nShmId[i] != -1 && m_bUseShm )
  289.                 {
  290.                     ShmHelp::DetachSharedRegion( &m_pcVideoBuf[i], &m_shmInfo[i] );
  291.                     m_nShmId[i] = -1;
  292.                 }
  293.                 else
  294.                 {
  295.                     HX_VECTOR_DELETE(m_pcVideoBuf[i]);
  296.                 }
  297.                 m_pcVideoBuf[i] = NULL;
  298.             }
  299.         }
  300.     }
  301.     
  302.     if( m_pXvImage )
  303.     {
  304.         for( i=0; i<m_nMultiBufferCount; i++ )
  305.         {
  306.             if( m_pXvImage[i] != NULL )
  307.             {
  308.                 XFree( m_pXvImage[i] );
  309.                 m_pXvImage[i] = NULL;
  310.             }
  311.         }
  312.     }
  313.     m_nVideoPitch = 0;
  314.     HX_ASSERT( m_display );
  315.     //Clear BitmapInfo struct....
  316.     HXBitmapInfo bmi;
  317.     memset( &bmi, 0, sizeof(HXBitmapInfo) );
  318.     int nResult = MakeBitmap( &bmi,
  319.                               sizeof(bmi),
  320.                               m_nSurfaceCID,
  321.                               m_surfaceSize.cx,
  322.                               m_surfaceSize.cy,
  323.                               NULL,
  324.                               0);
  325.     if( nResult )
  326.     {
  327.         ShmHelp::Init(m_display);
  328.         m_bUseShm = ShmHelp::ShmAvailable();
  329.         for( i=0 ; i<m_nMultiBufferCount ; i++ )
  330.         {
  331.             if( m_bUseShm )
  332.             {
  333.                 HX_RESULT retVal = ShmHelp::CreateSharedRegion( bmi.bmiHeader.biSizeImage,
  334.                                                                 &m_pcVideoBuf[i],
  335.                                                                 &m_nShmId[i],
  336.                                                                 &m_shmInfo[i]
  337.                                                                 );
  338.                 if( retVal != HXR_OK )
  339.                 {
  340.                     HX_ASSERT("Can't alloc shared memory segment." == NULL );
  341.                     m_nShmId[i]     = -1;
  342.                     m_pcVideoBuf[i] = NULL;
  343.                 }
  344.             }
  345.           
  346.             //did the shm alloc work?
  347.             if( m_pcVideoBuf[i] == NULL )
  348.             {
  349.                 m_bUseShm        = FALSE;
  350.                 m_nShmId[i]      = -1;
  351.                 m_pcVideoBuf[i]  = new UCHAR[bmi.bmiHeader.biSizeImage];
  352.             }
  353.             HX_ASSERT( m_pcVideoBuf );
  354.         }
  355.         m_nVideoPitch = GetBitmapPitch(&bmi);
  356.     }
  357.    
  358.     HX_ASSERT( m_nVideoPitch != 0 );
  359.     //Now create the XvImage to blt to.....
  360.     HX_ASSERT( m_nPortID != -1 );
  361.     for( i=0 ; i<m_nMultiBufferCount ; i++ )
  362.     {
  363.         HX_ASSERT( m_pXvImage[i] == NULL );
  364.         if( m_bUseShm )
  365.         {
  366.     XLockDisplay(m_display);
  367.             m_pXvImage[i]  = XvShmCreateImage( m_display,
  368.                                                m_nPortID,
  369.                                                m_ulFourCCID,
  370.                                                (char*)m_pcVideoBuf[i],
  371.                                                m_surfaceSize.cx,
  372.                                                m_surfaceSize.cy,
  373.                                                &m_shmInfo[i]
  374.                                                );
  375.     XUnlockDisplay(m_display);
  376.         }
  377.         else
  378.         {
  379.     XLockDisplay(m_display);
  380.             m_pXvImage[i] = XvCreateImage( m_display,
  381.                                            m_nPortID,
  382.                                            m_ulFourCCID,
  383.                                            (char*)m_pcVideoBuf[i],
  384.                                            m_surfaceSize.cx,
  385.                                            m_surfaceSize.cy
  386.                                            );
  387.     XUnlockDisplay(m_display);
  388.         }
  389.           
  390.         if( m_pXvImage[i] == NULL )
  391.         {
  392.             HX_ASSERT("Could not create overlay surface"==NULL );
  393.             //XXgfw, well, what to do here????
  394.         }
  395.     }
  396.     if( m_bUseShm )
  397.     {
  398.         //Find the shm completion event ID.
  399. XLockDisplay(m_display);
  400.         m_nCompletionEventID = XShmGetEventBase(m_display) + ShmCompletion;
  401. XUnlockDisplay(m_display);
  402.     }
  403.    
  404. #endif
  405. }
  406. BOOL CUnixSurf::_OverlayAvailable(int nFourCCWanted, int* pnPortID )
  407. {
  408.     BOOL bRetVal = FALSE;
  409.     
  410. #if defined(_LINUX) && defined(_OVERLAY)
  411.     if( !m_bUseOverlays )
  412.     {
  413.         return bRetVal;
  414.     }
  415.    
  416.     unsigned int nNumAdaptors = 0;
  417.     int nImageCount  = 0;
  418.     int nPortID      = -1;
  419.     int i = 0;
  420.     int j = 0;
  421.     int k = 0;
  422.     unsigned int ver = 0;
  423.     unsigned int rel = 0;
  424.     unsigned int req = 0;
  425.     unsigned int ev  = 0;
  426.     unsigned int err = 0;
  427.     int nRetCode = 0;
  428.     XvImageFormatValues *pImageFormats = NULL;
  429.     XvAdaptorInfo       *pAdaptorInfo  = NULL;
  430.     //First, we need to map our cid to a FourCC.
  431.     ULONG32 ulFourCC = 0;
  432.     switch(nFourCCWanted)
  433.     {
  434.        case -1:
  435.            //nothing requested
  436.            break;
  437.        case CID_I420:
  438.            ulFourCC = MAKEFOURCC('I','4','2','0');
  439.            break;
  440.        case CID_YV12:
  441.            ulFourCC = MAKEFOURCC('Y','V','1','2');
  442.            break;
  443.        case CID_YVU9:
  444.            ulFourCC = MAKEFOURCC('Y','V','U','9');
  445.            break;
  446.        case CID_YUY2:
  447.            ulFourCC = MAKEFOURCC('Y','U','Y','2');
  448.            break;
  449.        case CID_UYVY:
  450.            ulFourCC = MAKEFOURCC('U','Y','V','Y');
  451.            break;
  452.        default:
  453.            HX_ASSERT( "Unkown CID" == NULL );
  454.     }
  455.    
  456.     if( m_pSite )
  457.     {
  458.         HX_ASSERT( m_pSite->GetWindow() );
  459.         m_display = (Display*)((m_pSite->GetWindow())->display);
  460.     }
  461.     HX_ASSERT( m_display );
  462.     //XXXgfw this code assumes that there is *only* one overlay available
  463.     //on a machine. We need to change this as more become available....
  464.     if( zm_pXvOwner != NULL )
  465.     {
  466.         //Someone owns the *one* overlay
  467.         goto doneChecking;
  468.     }
  469.    
  470.     XLockDisplay(m_display);
  471.     nRetCode = XvQueryExtension(m_display, &ver, &rel, &req, &ev, &err);
  472.     XUnlockDisplay(m_display);
  473.     if( nRetCode != Success )
  474.     {
  475.         //Our X-Server doesn't support XVideo at all.
  476.         bRetVal = FALSE;
  477.         goto doneChecking;
  478.     }
  479.     XLockDisplay(m_display);
  480.     nRetCode = XvQueryAdaptors( m_display,
  481.                                 DefaultRootWindow(m_display),
  482.                                 &nNumAdaptors,
  483.                                 &pAdaptorInfo );
  484.     XUnlockDisplay(m_display);
  485.     if( nRetCode == Success && nNumAdaptors ) // pjg/gfw geForceII returns 0 adaptors with garbage return pointer
  486.     {
  487.         for(i=0 ; i<nNumAdaptors ; i++)
  488.         {
  489.             if(pAdaptorInfo[i].type & XvImageMask)
  490.             {
  491.                 if( ulFourCC==0 )
  492.                 {
  493.                     //User just wants to know if we have overlays at all.
  494.                     bRetVal = TRUE;
  495.                     goto doneChecking;
  496.                 }
  497.                 XLockDisplay(m_display);
  498.                 pImageFormats = XvListImageFormats(m_display, pAdaptorInfo[i].base_id, &nImageCount);  
  499.         XUnlockDisplay(m_display);
  500.                 for( j=0 ; j<nImageCount ; j++)
  501.                 {
  502.                     if(pImageFormats[j].id == ulFourCC)
  503.                     {
  504.                         for( k=0 ; k<pAdaptorInfo[i].num_ports; k++)
  505.                         {
  506. XLockDisplay(m_display);
  507. int nSuc = XvGrabPort(m_display, pAdaptorInfo[i].base_id+k, CurrentTime);
  508.                                 XUnlockDisplay(m_display);
  509.         if(Success == nSuc)
  510.                             {
  511.                                 //XXXgfw later, when we see graphics cards under linux
  512.                                 //that have more than one overlay available we will need
  513.                                 //to update this code......
  514.                         
  515.                                 //Hey! We found one!
  516.                                 nPortID = pAdaptorInfo[i].base_id+k;
  517. XLockDisplay(m_display);
  518.                                 XvUngrabPort(m_display,
  519.                                              pAdaptorInfo[i].base_id+k,
  520.                                              CurrentTime );
  521. XUnlockDisplay(m_display);
  522.                                 break;
  523.                             }
  524.                         }
  525.                     }
  526.                     if(nPortID != -1)
  527.                         break;
  528.                 }
  529.                 XFree(pImageFormats);
  530.             }
  531.             if(nPortID != -1)
  532.                 break;
  533.         }
  534.         XvFreeAdaptorInfo(pAdaptorInfo);
  535.       
  536.         if( nPortID != -1 )
  537.         {
  538.             bRetVal = TRUE;
  539.             if( NULL != pnPortID )
  540.                 *pnPortID = nPortID;
  541.             m_ulFourCCID = ulFourCC;
  542.         }
  543.       
  544. //        fprintf( stderr, "Found a port that supports %d(%p), it is %dn",
  545. //                 nFourCCWanted, (void*)ulFourCC,nPortID );
  546.     }
  547.   doneChecking:
  548. #endif   
  549.    
  550.     return bRetVal;
  551. }
  552. HX_RESULT CUnixSurf::_GetCaps(UINT32 *pfSurfaceCaps)
  553. {
  554.     *pfSurfaceCaps = 0;
  555.     if( _OverlayAvailable() )
  556.     {
  557.         *pfSurfaceCaps |= HX_OVERLAY;
  558.     }
  559.    
  560.     return HXR_OK;
  561. }
  562. HX_RESULT CUnixSurf::_CreateOverlay(BOOL bOverlay, int cid, int x, int y)
  563. {
  564.     HX_RESULT retVal = HXR_FAIL;
  565.     int       nSuc   = Success;
  566. //     fprintf( stderr, "CUnixSurf::_CreateOverlay(%p): bOverlay:%d cid:%d x,y: %d %dn",
  567. //              this, bOverlay, cid, x, y);
  568.     if( x & 15 )
  569.     {
  570.         x = (x&~15)+16;
  571.     }
  572. #if defined(_LINUX) && defined(_OVERLAY) 
  573.     if( bOverlay )
  574.     {
  575.         int  nPortID    = 0;
  576.         BOOL bAvailable = FALSE;
  577.         bAvailable = _OverlayAvailable( cid, &nPortID );
  578.         if( bAvailable )
  579.         {
  580.             HX_ASSERT(m_display);
  581.             //Grab the port.
  582.      XLockDisplay(m_display);
  583.             nSuc = XvGrabPort( m_display, nPortID, CurrentTime );
  584.      XUnlockDisplay(m_display);
  585.             if( nSuc == Success )
  586.             {
  587.                 //Take ownership of the overlay. A connection to the XServer
  588.                 //can grab the overlay port as much as it wants so we can't
  589.                 //rely on that to make sure that we only have one surface 
  590.                 //using the overlay.
  591.                 m_nPortID   = nPortID;
  592.                 zm_pXvOwner = this;
  593.             
  594.                 //So far so good. Now we need to grab all of our atoms to control
  595.                 //the overlay
  596. XLockDisplay(m_display);
  597.                 m_atomColorKey = XInternAtom(m_display, "XV_COLOR_KEY", True);
  598. XUnlockDisplay(m_display);
  599.                 if( m_atomColorKey == None )
  600.                 {
  601.                     //There isn't a naming convention for any of these atoms. we
  602.                     //have to disover at run time what they are.
  603.     XLockDisplay(m_display);
  604.                     m_atomColorKey  = XInternAtom(m_display, "XV_COLORKEY", True);
  605.     XUnlockDisplay(m_display);
  606.                 }
  607.                 XLockDisplay(m_display);
  608.                 m_atomClipKey    = XInternAtom(m_display, "XV_PAINT_CLIPLIST", True);
  609. XUnlockDisplay(m_display);
  610.                 //Now set some of the atoms we read from the prefs
  611.                 if( None != m_atomClipKey)
  612.                 {
  613.      XLockDisplay(m_display);
  614.                     XvSetPortAttribute(m_display, m_nPortID, m_atomClipKey, m_bPaintClipList);
  615.      XUnlockDisplay(m_display);
  616.                 }            
  617. #if defined(HELIX_FEATURE_HARDWARE_COLOR_CONTROLS)
  618. XLockDisplay(m_display);
  619.                 m_atomBrightness = XInternAtom(m_display, "XV_BRIGHTNESS", True);
  620.                 m_atomContrast   = XInternAtom(m_display, "XV_CONTRAST", True);
  621.                 m_atomHue        = XInternAtom(m_display, "XV_HUE", True);
  622.                 m_atomSaturation = XInternAtom(m_display, "XV_SATURATION", True);
  623.                 //Get the min and max values for each settable atom.
  624.                 int nNumAttributes = 0;
  625.                 XvAttribute* pPAList = XvQueryPortAttributes( m_display,
  626.                                                               m_nPortID,
  627.                                                               &nNumAttributes );
  628. XUnlockDisplay(m_display);
  629.                 for( int nIdx=0; nIdx < nNumAttributes; nIdx++ )
  630.                 {
  631.                     const char* pszName = pPAList[nIdx].name;
  632.                     int         nMin    = pPAList[nIdx].min_value;
  633.                     int         nMax    = pPAList[nIdx].max_value;
  634.                     
  635.                     stPortAttribute paTmp(nMin, nMax);
  636.                     
  637.                     if( !strcmp(pszName, "XV_BRIGHTNESS" ))
  638.                     {
  639.          XLockDisplay(m_display);
  640.                         XvGetPortAttribute( m_display, m_nPortID, m_atomBrightness, &m_nCurrBrightness );
  641. XUnlockDisplay(m_display);
  642.                         paBrightness = paTmp;
  643.                     }
  644.                     if( !strcmp(pszName, "XV_CONTRAST" ))
  645.                     {
  646.          XLockDisplay(m_display);
  647.                         XvGetPortAttribute( m_display, m_nPortID, m_atomContrast, &m_nCurrContrast );
  648. XUnlockDisplay(m_display);
  649.                         paContrast = paTmp;
  650.                     }
  651.                     if( !strcmp(pszName, "XV_HUE" ))
  652.                     {
  653.          XLockDisplay(m_display);
  654.                         XvGetPortAttribute( m_display, m_nPortID, m_atomHue, &m_nCurrHue );
  655. XUnlockDisplay(m_display);
  656.                         paHue = paTmp;
  657.                     }
  658.                     if( !strcmp(pszName, "XV_SATURATION" ))
  659.                     {
  660.          XLockDisplay(m_display);
  661.                         XvGetPortAttribute( m_display, m_nPortID, m_atomSaturation, &m_nCurrSaturation );
  662. XUnlockDisplay(m_display);
  663.                         paSaturation = paTmp;
  664.                     }
  665.                 }
  666.                 
  667.                 if( pPAList )
  668.     XFree( pPAList );
  669. #endif
  670.                 //Now we need to create the overlay surface???
  671.                 m_surfaceSize.cx = x;
  672.                 m_surfaceSize.cy = y;
  673.                 m_nSurfaceCID    = cid;
  674.                 m_nBltMode       = HX_OVERLAY_BLT;
  675.                 _CreateBuffer();
  676.                 //Return good.
  677.                 retVal = HXR_OK;
  678.             }
  679.         }
  680.     } //if(bOverlay)...
  681. #endif   
  682.     return retVal;
  683. }
  684. HX_RESULT CUnixSurf::_LockInternalSurface( UCHAR**  ppSurfPtr,
  685.                                            LONG32*  pnSurfPitch,
  686.                                            HXxSize& notused )
  687. {
  688.     HX_RESULT retVal = HXR_OK;
  689.     //Flip internal buffers....
  690.     m_nCurrentBuffer++;
  691.     if( m_nCurrentBuffer >= m_nMultiBufferCount )
  692.     {
  693.         m_nCurrentBuffer=0;
  694.     }
  695.     HX_ASSERT( m_pcVideoBuf[m_nCurrentBuffer] );
  696.     HX_ASSERT( m_nVideoPitch != 0 );
  697.    
  698.     *ppSurfPtr   = (UCHAR*)m_pcVideoBuf[m_nCurrentBuffer];
  699.     *pnSurfPitch = m_nVideoPitch;
  700.     return retVal;
  701. }
  702. HX_RESULT CUnixSurf::_UnlockInternalSurface(UCHAR* pSurfPtr)
  703. {
  704.     return HXR_OK;
  705. }
  706. void CUnixSurf::_SetupDCObjects(HXxDC hxxDC, void** phOldBrush, void** phOldPen)
  707. {
  708. }
  709. void CUnixSurf::_FillRectangle(HXxDC hxxDC,
  710.                                UINT32 left, UINT32 top,
  711.                                UINT32 right, UINT32 bottom)
  712. {
  713.     if( !hxxDC )
  714.         return;
  715.     // XXXNH: constrain ourselves to the current image size.  When the site
  716.     // is shrunk (eg: via user action) we can enter a situation where a
  717.     // damaged rect is queued up for drawing that is larger than the current
  718.     // image.  We will crash if we don't constrain it to the current size.
  719.     XImage* pImage = (XImage*)hxxDC;
  720.     if (right > pImage->width)
  721. right = pImage->width;
  722.     if (bottom > pImage->height)
  723. bottom = pImage->height;
  724.     for( int x=left; x<=right-1; x++ )
  725.     {
  726.         for( int y=top; y<=bottom-1; y++ )
  727.         {
  728. #if defined _LINUX &&  defined _OVERLAY
  729.             XPutPixel( pImage, x, y, m_ulColorKey );
  730. #endif
  731.         }
  732.     }
  733. }
  734. void CUnixSurf::_RestoreDCObjects(HXxDC hxxDC, void* hOldBrush, void* hOldPen)
  735. {
  736. }
  737. void CUnixSurf::_GetCompositionSurfaceHXxDC(HXxDC *hdc)
  738. {
  739.     //This needs to return a drawable that points to the composition surface...
  740.     CUnixRootSurf* pSurface = (CUnixRootSurf*)m_pSite->GetRootSurface();
  741.     XImage *pImage = pSurface->_GetCompositionSurfaceDrawable();
  742.     *hdc = (HXxDC)pImage;
  743. }
  744. void CUnixSurf::_ReleaseCompositionSurfaceHXxDC(HXxDC hdc)
  745. {
  746.     //Nothing to do on unix...
  747. }
  748. INT32 CUnixSurf::_InsureColorMatch(INT32 InColor)
  749. {
  750.     return InColor;
  751. }
  752. void CUnixSurf::_SetColorKey(INT32 nColorSpaceLowValue,INT32 nColorSpaceHighValue)
  753. {
  754. #if defined(_LINUX) && defined(_OVERLAY)   
  755.     static BOOL bDoneItAlready = FALSE;
  756.    
  757.     if( m_atomColorKey != None && !bDoneItAlready)
  758.     {
  759.         if( m_ulColorKey == 0x01020304 )
  760.         {
  761.             m_ulColorKey = nColorSpaceHighValue;
  762.             //The user did not set a color key preference...
  763.      XLockDisplay(m_display);
  764.             XvSetPortAttribute( m_display, m_nPortID, m_atomColorKey, nColorSpaceHighValue );
  765.      XUnlockDisplay(m_display);
  766.         }
  767.         else
  768.         {
  769.             XLockDisplay(m_display);
  770.             XvSetPortAttribute( m_display, m_nPortID, m_atomColorKey, m_ulColorKey );
  771.      XUnlockDisplay(m_display);
  772.         }
  773.         bDoneItAlready = TRUE;
  774.     }
  775. #endif   
  776. }
  777. static BOOL CheckIt(Display* dis, XEvent* event, XPointer arg)
  778. {
  779.     BOOL ret = (event->type==(int)arg);
  780.     return ret;
  781. }
  782. #if defined(HELIX_FEATURE_HARDWARE_COLOR_CONTROLS)
  783. inline int _scaleIt( float v, stPortAttribute at )
  784. {
  785.     int nRetVal = (int)(((v+1)*(at.nMaxValue-at.nMinValue))/2+at.nMinValue);
  786.     if( nRetVal < at.nMinValue )
  787.         nRetVal = at.nMinValue;
  788.     if( nRetVal > at.nMaxValue )
  789.         nRetVal = at.nMaxValue;
  790. }
  791. BOOL CUnixSurf::HasHWColorConrols()
  792. {
  793.     BOOL retVal=FALSE;
  794.     if( None != m_atomBrightness &&
  795.         None != m_atomHue        &&
  796.         None != m_atomSaturation &&
  797.         None != m_atomContrast )
  798.     {
  799.         retVal = TRUE;
  800.     }
  801.     return retVal;
  802. }
  803. void CUnixSurf::SetHWColorControls()
  804. {
  805.     float fBright     = m_pSite->GetBrightness();
  806.     float fContrast   = m_pSite->GetContrast();
  807.     float fHue        = m_pSite->GetHue();
  808.     float fSaturation = m_pSite->GetSaturation();
  809.     if( None != m_atomBrightness )
  810.     {
  811.         int nVal = _scaleIt( fBright, paBrightness);
  812.         if( nVal != m_nCurrBrightness )
  813.         {
  814.      XLockDisplay(m_display);
  815.             XvSetPortAttribute(m_display, m_nPortID, m_atomBrightness, nVal);
  816.      XUnlockDisplay(m_display);
  817.             m_nCurrBrightness = nVal;
  818.         }
  819.     }            
  820.     if( None != m_atomContrast)
  821.     {
  822.         int nVal = _scaleIt( fContrast, paContrast);
  823.         if( nVal != m_nCurrContrast )
  824.         {
  825.      XLockDisplay(m_display);
  826.             XvSetPortAttribute(m_display, m_nPortID, m_atomContrast, nVal);
  827.      XUnlockDisplay(m_display);
  828.             m_nCurrContrast = nVal;
  829.         }
  830.     }            
  831.     if( None != m_atomHue)
  832.     {
  833.         int nVal = _scaleIt( fHue, paHue);
  834.         if( nVal != m_nCurrHue )
  835.         {
  836.     XLockDisplay(m_display);
  837.             XvSetPortAttribute(m_display, m_nPortID, m_atomHue, nVal);
  838.     XUnlockDisplay(m_display);
  839.             m_nCurrHue = nVal;
  840.         }
  841.     }            
  842.     if( None != m_atomSaturation)
  843.     {
  844.         int nVal = _scaleIt( fSaturation, paSaturation);
  845.         if( nVal != m_nCurrSaturation )
  846.         {
  847.      XLockDisplay(m_display);
  848.             XvSetPortAttribute(m_display, m_nPortID, m_atomSaturation, nVal);
  849.      XUnlockDisplay(m_display);
  850.             m_nCurrSaturation = nVal;
  851.         }
  852.     }
  853. }
  854. #endif        
  855. void CUnixSurf::_UpdateOverlay(HXxRect* dest, HXxRect* src, INT32 inFlags)
  856. {
  857.     HXxWindow*        pWin         = m_pSite->GetWindow();
  858.     CBaseRootSurface* pRootSurface = m_pSite->GetRootSurface();
  859.     int               nRet         = 0;
  860.     Window            winSurface   = 0;
  861.     HXxRect           rectDest     = {0,0,0,0};
  862.     memcpy( &rectDest, dest, sizeof( HXxRect ) ); /* Flawfinder: ignore */
  863.     HX_ASSERT( m_nMultiBufferCount );
  864. #if defined(_LINUX) && defined(_OVERLAY)
  865.     m_ulLastOverlayUpdateTime = HX_GET_TICKCOUNT();
  866.    
  867.     //Draw on the root window if the user wants it. This feature isn't tested
  868.     //and has known problems for certain window managers that create their own
  869.     //window over the root. Looks really cool when it works though. :) Turn
  870.     //this on set the color key to the background color of all your xterms.
  871.     //Very nice.
  872.     if( !m_bWallPaperMode )
  873.     {
  874.         winSurface = (Window)pWin->window;
  875.     }
  876.     else
  877.     {
  878.         winSurface = DefaultRootWindow(m_display);
  879.     }
  880.    
  881.     HX_ASSERT( pWin );
  882. #ifdef _DEBUG   
  883. //     static ULONG32 ulLast  =0;
  884. //     static ULONG32 ulCount =0;
  885. //     static ULONG32 ulCountTot =0;
  886. //     static double  fpsTot=0;
  887. //     ULONG32        ulCurr  = HX_GET_TICKCOUNT();
  888. //     if( ulCurr-ulLast>1000 )
  889. //     {
  890. //        float fps = (float)ulCount/((float)(ulCurr-ulLast)/1000.0);
  891. //        fpsTot += fps;
  892. //        ulCountTot++;
  893.       
  894. //        fprintf( stderr, "%lu elapsed microseconds. %lu frames.  %f FPS (Ave: %f)n",
  895. //                 ulCurr-ulLast, ulCount, fps, fpsTot/(double)ulCountTot );
  896. //        ulCount = 0;
  897. //        ulLast  = ulCurr;
  898. //     }
  899. //     ulCount++;
  900. #endif   
  901.     //if we are on the root window, calculate new dest rect.
  902.     //Copy the one passed in.
  903.     if( m_bWallPaperMode )
  904.     {
  905.  XLockDisplay(m_display);
  906.         Screen* pScreen = XDefaultScreenOfDisplay(m_display);
  907.  XUnlockDisplay(m_display);
  908.         UINT16 uHorzRes = WidthOfScreen(pScreen);
  909.         UINT16 uVertRes = HeightOfScreen(pScreen);
  910.         //if the user wants to stretchtofill then make the dest rect the
  911.         //whole screen, otherwise preserve aspec ration.
  912.         if( m_bStretchToFill )
  913.         {
  914.             //Make it the whole screen.
  915.             rectDest.left   = 0;
  916.             rectDest.top    = 0;
  917.             rectDest.right  = uHorzRes;
  918.             rectDest.bottom = uVertRes;
  919.         }
  920.         else
  921.         {
  922.             //maintain aspect ration.
  923.             //Scale it.
  924.             float fXScale   = (float)uHorzRes/(float)(dest->right-dest->left);
  925.             float fYScale   = (float)uVertRes/(float)(dest->bottom-dest->top);
  926.             float fScale    = (fXScale<fYScale) ? fXScale : fYScale;
  927.             int nWidth      = (int)(fScale*(dest->right-dest->left)+.5);
  928.             int nHeight     = (int)(fScale*(dest->bottom-dest->top)+.5);
  929.             rectDest.left   = 0;
  930.             rectDest.top    = 0;
  931.          
  932.             if( nWidth<uHorzRes )
  933.                 rectDest.left = (uHorzRes-nWidth)/2;
  934.             if( nHeight<uVertRes )
  935.                 rectDest.top  = (uVertRes-nHeight)/2;
  936.             rectDest.right  = rectDest.left+nWidth;
  937.             rectDest.bottom = rectDest.top+nHeight;
  938.         }
  939.     }
  940.     if( m_bUseShm )
  941.     {
  942.  XLockDisplay(m_display);
  943.         nRet = XvShmPutImage( m_display,
  944.                               m_nPortID,
  945.                               winSurface,
  946.                               ((CUnixRootSurf*)pRootSurface)->GetGC(),
  947.                               m_pXvImage[m_nCurrentBuffer],
  948.                               src->left, 
  949.                               src->top,
  950.                               src->right - src->left, 
  951.                               src->bottom - src->top,
  952.                               rectDest.left, 
  953.                               rectDest.top,
  954.                               rectDest.right - rectDest.left,      
  955.                               rectDest.bottom - rectDest.top,
  956.                               True
  957.                               );
  958. XUnlockDisplay(m_display);
  959.     }
  960.     else
  961.     {
  962.         XLockDisplay(m_display);
  963.         nRet = XvPutImage( m_display,
  964.                            m_nPortID, 
  965.                            winSurface,
  966.                            ((CUnixRootSurf*)pRootSurface)->GetGC(),
  967.                            m_pXvImage[m_nCurrentBuffer],    
  968.                            src->left, 
  969.                            src->top,
  970.                            src->right - src->left, 
  971.                            src->bottom - src->top,
  972.                            rectDest.left, 
  973.                            rectDest.top,
  974.                            rectDest.right - rectDest.left,      
  975.                            rectDest.bottom - rectDest.top
  976.                            );
  977. XUnlockDisplay(m_display);
  978.     }
  979.     if( m_bUseShm && m_nMultiBufferCount==1 )
  980.     {
  981.         //If we aren't at least double buffering and we are using
  982.         //shared memory, make sure we wait for the completion of the
  983.         //copy of the shared memory segment to the server. Tear not
  984.         //want not.
  985.         HX_ASSERT( m_nCompletionEventID > 0 );
  986.         XEvent event;
  987.  XLockDisplay(m_display);
  988.         XIfEvent( m_display, &event, CheckIt, (XPointer)m_nCompletionEventID );
  989.  XUnlockDisplay(m_display);
  990.     }
  991.    
  992. #endif   
  993. }
  994. BOOL CUnixSurf::_IsSurfaceVisible()
  995. {
  996.     return TRUE;
  997. }
  998. void CUnixSurf::_ReleaseSurface()
  999. {
  1000.     int i=0;
  1001.     
  1002. #if defined(_LINUX) && defined(_OVERLAY)   
  1003.     //Release all of our overlay resources.....
  1004.     if( m_nPortID!=-1 )
  1005.     {
  1006.         XLockDisplay(m_display);
  1007.         XvUngrabPort( m_display, m_nPortID, CurrentTime );
  1008.  XUnlockDisplay(m_display);
  1009.         m_nPortID=-1;
  1010.         if( zm_pXvOwner==this )
  1011.         {
  1012.             zm_pXvOwner = NULL;
  1013.         }
  1014.     }
  1015.     if( m_pcVideoBuf != NULL )
  1016.     {
  1017.         for( i=0 ; i<m_nMultiBufferCount ; i++ )
  1018.         {
  1019.             if( m_nShmId[i] != -1 && m_bUseShm )
  1020.             {
  1021.                 ShmHelp::DetachSharedRegion( &m_pcVideoBuf[i], &m_shmInfo[i] );
  1022.                 m_nShmId[i] = -1;
  1023.             }
  1024.             else
  1025.             {
  1026.                 HX_VECTOR_DELETE(m_pcVideoBuf[i]);
  1027.             }
  1028.             m_pcVideoBuf[i] = NULL;
  1029.         }
  1030.     }
  1031.     
  1032.     if( m_pXvImage )
  1033.     {
  1034.         for( i=0; i<m_nMultiBufferCount; i++ )
  1035.         {
  1036.             XFree( m_pXvImage[i] );
  1037.             m_pXvImage[i] = NULL;
  1038.         }
  1039.     }
  1040.     memset( &m_surfaceSize, 0, sizeof(m_surfaceSize) );
  1041.     m_nSurfaceCID = 1234; //what else?
  1042. #endif   
  1043. }
  1044. HXxDC CUnixSurf::_GetDC(HXxWindow*)
  1045. {
  1046.     return (HXxDC)m_GC;
  1047. }
  1048. void CUnixSurf::_ReleaseDC(HXxWindow*, HXxDC)
  1049. {
  1050. }
  1051. void CUnixSurf::_GetWindowDeviceCords(HXxRect* rect )
  1052. {
  1053.     memset( rect, 0, sizeof( HXxRect) );
  1054. }