diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /mp/src/vgui2/chromehtml/chromewrapper.cpp | |
| parent | Mark some more files as text. (diff) | |
| download | source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip | |
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/vgui2/chromehtml/chromewrapper.cpp')
| -rw-r--r-- | mp/src/vgui2/chromehtml/chromewrapper.cpp | 882 |
1 files changed, 441 insertions, 441 deletions
diff --git a/mp/src/vgui2/chromehtml/chromewrapper.cpp b/mp/src/vgui2/chromehtml/chromewrapper.cpp index 179974f0..88f6ee9d 100644 --- a/mp/src/vgui2/chromehtml/chromewrapper.cpp +++ b/mp/src/vgui2/chromehtml/chromewrapper.cpp @@ -1,441 +1,441 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Creates a HTML control
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "winlite.h"
-#include "html_chrome.h"
-#include "tier1/interface.h"
-#include "reliabletimer.h"
-#include "htmlmanager.h"
-
-#include "html/htmlprotobuf.h"
-#include <html/ichromehtmlwrapper.h>
-
-//-----------------------------------------------------------------------------
-// Purpose: owner object that gets responses from the CEF thread and dispatches them
-//-----------------------------------------------------------------------------
-class CHTMLController : public IHTMLChromeController
-{
-public:
- CHTMLController() { m_BrowserSerial = 0; m_nCefTargetFrameRate = 0; SetDefLessFunc( m_mapBrowserRequests ); SetDefLessFunc( m_mapBrowsers ); }
- ~CHTMLController() {}
-
- bool Init( const char *pchHTMLCacheDir, const char *pchCookiePath );
- void Shutdown();
-
- void SetWebCookie( const char *pchHostname, const char *pchKey, const char *pchValue, const char *pchPath, RTime32 nExpires );
- void GetWebCookiesForURL( CUtlString *pstrValue, const char *pchURL, const char *pchName );
- void SetClientBuildID( uint64 ulBuildID );
-
- bool BHasPendingMessages();
-
- void CreateBrowser( IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier );
- void RemoveBrowser( IHTMLResponses *pBrowser );
- bool RunFrame();
-
- void WakeThread() { AccessHTMLWrapper().WakeThread(); }
- HTMLCommandBuffer_t *GetFreeCommandBuffer( EHTMLCommands eCmd, int iBrowser ) { return AccessHTMLWrapper().GetFreeCommandBuffer( eCmd, iBrowser ); }
- void PushCommand( HTMLCommandBuffer_t *pCmd ) { AccessHTMLWrapper().PushCommand( pCmd ); }
-
-
- bool GetMainThreadCommand( HTMLCommandBuffer_t **pCmd ) { return AccessHTMLWrapper().GetMainThreadCommand( pCmd ); }
- void ReleaseCommandBuffer( HTMLCommandBuffer_t *pCmd ) { AccessHTMLWrapper().ReleaseCommandBuffer( pCmd ); }
-
-#ifdef DBGFLAG_VALIDATE
- void Validate( CValidator &validator, const char *pchName );
- bool ChromePrepareForValidate();
- bool ChromeResumeFromValidate();
-#endif
-
- void SetCefThreadTargetFrameRate( uint32 nFPS );
-
-private:
- // keeps track of outstanding browser create requests
- CUtlMap< uint32, IHTMLResponses *, int > m_mapBrowserRequests;
- // the next unique identifier to use when doing a browser create
- uint32 m_BrowserSerial;
- // the map of browser handles to our html panel objects, used for cef thread command dispatching
- CUtlMap< uint32, IHTMLResponses *, int > m_mapBrowsers;
-
- int m_nCefTargetFrameRate;
-};
-
-
-static CHTMLController s_HTMLController;
-EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CHTMLController, IHTMLChromeController, CHROMEHTML_CONTROLLER_INTERFACE_VERSION, s_HTMLController );
-
-
-//-----------------------------------------------------------------------------
-// Purpose: request the cef thread to make a new browser
-//-----------------------------------------------------------------------------
-void CHTMLController::CreateBrowser( IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier )
-{
- m_BrowserSerial++;
- m_mapBrowserRequests.Insert( m_BrowserSerial, pBrowser );
-
- CHTMLProtoBufMsg<CMsgBrowserCreate> cmd( eHTMLCommands_BrowserCreate );
- cmd.Body().set_request_id( m_BrowserSerial );
- cmd.Body().set_popup( bPopupWindow );
- cmd.Body().set_useragent( pchUserAgentIdentifier );
- HTMLCommandBuffer_t *pBuf = AccessHTMLWrapper().GetFreeCommandBuffer( eHTMLCommands_BrowserCreate, -1 );
- cmd.SerializeCrossProc( &pBuf->m_Buffer );
- AccessHTMLWrapper().PushCommand( pBuf );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: delete a browser we have
-//-----------------------------------------------------------------------------
-void CHTMLController::RemoveBrowser( IHTMLResponses *pBrowser )
-{
-
- // pull ourselves from the browser handle list as we are doing away
- FOR_EACH_MAP_FAST( m_mapBrowsers, i)
- {
- if ( m_mapBrowsers[i] == pBrowser )
- {
- // tell the cef thread this browser is going away
- CHTMLProtoBufMsg<CMsgBrowserRemove> cmd( eHTMLCommands_BrowserRemove );
- cmd.Body().set_browser_handle( pBrowser->BrowserGetIndex() );
- HTMLCommandBuffer_t *pBuf = AccessHTMLWrapper().GetFreeCommandBuffer( eHTMLCommands_BrowserRemove, pBrowser->BrowserGetIndex() );
- cmd.SerializeCrossProc( &pBuf->m_Buffer );
- AccessHTMLWrapper().PushCommand( pBuf );
-
- // now kill it
- m_mapBrowsers.RemoveAt( i );
- }
- }
-
- // also remove us from pending list if in it
- FOR_EACH_MAP_FAST( m_mapBrowserRequests, i)
- {
- if ( m_mapBrowserRequests[i] == pBrowser )
- m_mapBrowserRequests.RemoveAt( i );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: turn on the cef engine
-//-----------------------------------------------------------------------------
-bool CHTMLController::Init( const char *pchHTMLCacheDir, const char *pchCookiePath )
-{
-#if !defined(WIN64) && !defined(STATIC_TIER0)
- ChromeInit( pchHTMLCacheDir, pchCookiePath );
-#endif
-
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: shutdown chrome
-//-----------------------------------------------------------------------------
-void CHTMLController::Shutdown()
-{
-#if !defined(WIN64) && !defined(STATIC_TIER0)
- ChromeShutdown();
-#endif
-}
-
-
-
-// helper macro to dispatch messages from the cef thread
-#define HTML_MSG_FUNC( eHTMLCommand, bodyType, commandFunc ) \
- case eHTMLCommand: \
-{ \
- CHTMLProtoBufMsg< bodyType > cmd( pCmd->m_eCmd ); \
- if ( !cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) ) \
-{ \
- bError = true; \
-} \
- else \
-{ \
- int idx = m_mapBrowsers.Find( cmd.BodyConst().browser_handle() ); \
- if ( idx != m_mapBrowsers.InvalidIndex() ) \
-{ \
- if ( m_mapBrowsers[idx] ) \
- m_mapBrowsers[idx]->commandFunc( &cmd.BodyConst() ); \
-} \
-} \
-} \
- break; \
-
-
-//-----------------------------------------------------------------------------
-// Purpose: process any ipc responses we have pending
-//-----------------------------------------------------------------------------
-bool CHTMLController::RunFrame()
-{
- VPROF_BUDGET( "CHTMLController::RunFrame", VPROF_BUDGETGROUP_TENFOOT );
- HTMLCommandBuffer_t *pCmd;
- bool bError = false;
- bool bDidwork = false;
-
- // Paint messages are dispatched last to avoid doing excessive work on
- // the main thread when two paint messages have stacked up in the queue.
- // This could be greatly optimized by doing atomic buffer swaps instead
- // of pushing the paint updates through a queue, but this helps for now.
- // -henryg
- CUtlVector< HTMLCommandBuffer_t * > vecDeferredPaint;
-
- while( GetMainThreadCommand( &pCmd ) )
- {
- bool bRelease = true;
- bDidwork = true;
- //Msg( "Got response %d\n", pCmd->m_eCmd );
- switch( pCmd->m_eCmd )
- {
- default:
- break;
- case eHTMLCommands_BrowserCreateResponse:
- {
- CHTMLProtoBufMsg< CMsgBrowserCreateResponse > cmd( pCmd->m_eCmd );
- if ( !cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) )
- {
- bError = true;
- }
- else
- {
- int idx = m_mapBrowserRequests.Find( cmd.BodyConst().request_id() );
- if ( idx != m_mapBrowserRequests.InvalidIndex() )
- {
- m_mapBrowsers.Insert( cmd.BodyConst().browser_handle(), m_mapBrowserRequests[idx] );
- m_mapBrowserRequests[idx]->BrowserSetIndex( cmd.BodyConst().browser_handle() );
- m_mapBrowserRequests.RemoveAt( idx );
- }
- }
- }
- break;
- case eHTMLCommands_NeedsPaint:
- {
- bRelease = false;
- vecDeferredPaint.AddToTail( pCmd );
- }
- break;
-
- HTML_MSG_FUNC( eHTMLCommands_BrowserReady, CMsgBrowserReady, BrowserReady );
- HTML_MSG_FUNC( eHTMLCommands_StartRequest, CMsgStartRequest, BrowserStartRequest );
- HTML_MSG_FUNC( eHTMLCommands_URLChanged, CMsgURLChanged, BrowserURLChanged );
- HTML_MSG_FUNC( eHTMLCommands_FinishedRequest, CMsgFinishedRequest, BrowserFinishedRequest );
- HTML_MSG_FUNC( eHTMLCommands_ShowPopup, CMsgShowPopup, BrowserShowPopup );
- HTML_MSG_FUNC( eHTMLCommands_HidePopup, CMsgHidePopup, BrowserHidePopup );
- HTML_MSG_FUNC( eHTMLCommands_OpenNewTab, CMsgOpenNewTab, BrowserOpenNewTab );
- HTML_MSG_FUNC( eHTMLCommands_PopupHTMLWindow, CMsgPopupHTMLWindow, BrowserPopupHTMLWindow );
- HTML_MSG_FUNC( eHTMLCommands_SetHTMLTitle, CMsgSetHTMLTitle, BrowserSetHTMLTitle );
- HTML_MSG_FUNC( eHTMLCommands_LoadingResource, CMsgLoadingResource, BrowserLoadingResource );
- HTML_MSG_FUNC( eHTMLCommands_StatusText, CMsgStatusText, BrowserStatusText );
- HTML_MSG_FUNC( eHTMLCommands_SetCursor, CMsgSetCursor, BrowserSetCursor );
- HTML_MSG_FUNC( eHTMLCommands_FileLoadDialog, CMsgFileLoadDialog, BrowserFileLoadDialog );
- HTML_MSG_FUNC( eHTMLCommands_ShowToolTip, CMsgShowToolTip, BrowserShowToolTip );
- HTML_MSG_FUNC( eHTMLCommands_UpdateToolTip, CMsgUpdateToolTip, BrowserUpdateToolTip );
- HTML_MSG_FUNC( eHTMLCommands_HideToolTip, CMsgHideToolTip, BrowserHideToolTip );
- HTML_MSG_FUNC( eHTMLCommands_SearchResults, CMsgSearchResults, BrowserSearchResults );
- HTML_MSG_FUNC( eHTMLCommands_Close, CMsgClose, BrowserClose );
- HTML_MSG_FUNC( eHTMLCommands_GetZoomResponse, CMsgGetZoomResponse, BrowserGetZoomResponse );
- HTML_MSG_FUNC( eHTMLCommands_HorizontalScrollBarSizeResponse, CMsgHorizontalScrollBarSizeResponse, BrowserHorizontalScrollBarSizeResponse );
- HTML_MSG_FUNC( eHTMLCommands_VerticalScrollBarSizeResponse, CMsgVerticalScrollBarSizeResponse, BrowserVerticalScrollBarSizeResponse );
- HTML_MSG_FUNC( eHTMLCommands_LinkAtPositionResponse, CMsgLinkAtPositionResponse, BrowserLinkAtPositionResponse );
- HTML_MSG_FUNC( eHTMLCommands_ZoomToElementAtPositionResponse, CMsgZoomToElementAtPositionResponse, BrowserZoomToElementAtPositionResponse );
- HTML_MSG_FUNC( eHTMLCommands_JSAlert, CMsgJSAlert, BrowserJSAlert );
- HTML_MSG_FUNC( eHTMLCommands_JSConfirm, CMsgJSConfirm, BrowserJSConfirm );
- HTML_MSG_FUNC( eHTMLCommands_OpenSteamURL, CMsgOpenSteamURL, BrowserOpenSteamURL );
- HTML_MSG_FUNC( eHTMLCommands_CanGoBackandForward, CMsgCanGoBackAndForward, BrowserCanGoBackandForward );
- HTML_MSG_FUNC( eHTMLCommands_SizePopup, CMsgSizePopup, BrowserSizePopup );
- HTML_MSG_FUNC( eHTMLCommands_ScaleToValueResponse, CMsgScalePageToValueResponse, BrowserScalePageToValueResponse );
- HTML_MSG_FUNC( eHTMLCommands_RequestFullScreen, CMsgRequestFullScreen, BrowserRequestFullScreen );
- HTML_MSG_FUNC( eHTMLCommands_ExitFullScreen, CMsgExitFullScreen, BrowserExitFullScreen );
- HTML_MSG_FUNC( eHTMLCommands_GetCookiesForURLResponse, CMsgGetCookiesForURLResponse, BrowserGetCookiesForURLResponse );
- HTML_MSG_FUNC( eHTMLCommands_NodeGotFocus, CMsgNodeHasFocus, BrowserNodeGotFocus );
- HTML_MSG_FUNC( eHTMLCommands_SavePageToJPEGResponse, CMsgSavePageToJPEGResponse, BrowserSavePageToJPEGResponse );
- HTML_MSG_FUNC( eHTMLCommands_GetFocusedNodeValueResponse, CMsgFocusedNodeTextResponse, BrowserFocusedNodeValueResponse );
- }
- if ( bError )
- {
- Warning( "Failed to parse command %d", pCmd->m_eCmd );
- Assert( !"Bad Command" );
- }
- if ( bRelease )
- {
- ReleaseCommandBuffer( pCmd );
- }
- }
-
- // Collapse deferred paints by browser ID and process them; the latest texture always
- // has fully updated bits, we simply union its dirty rect with the skipped updates.
- // Note: browser resizes always include a full dirty rect, we don't have to check here.
- while ( vecDeferredPaint.Count() )
- {
- // Pull the last paint off the queue
- pCmd = vecDeferredPaint[ vecDeferredPaint.Count() - 1 ];
- int iBrowser = pCmd->m_iBrowser;
- CHTMLProtoBufMsg<CMsgNeedsPaint> cmd( eHTMLCommands_NeedsPaint );
- DbgVerify( cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) );
- ReleaseCommandBuffer( pCmd );
- vecDeferredPaint.Remove( vecDeferredPaint.Count() - 1 );
-
-
- CMsgNeedsPaint &body = cmd.Body();
- CChromeUpdateRegion region;
- if ( body.updatewide() && body.updatetall() )
- {
- region.MarkDirtyRect( body.updatex(), body.updatey(), body.updatex() + body.updatewide(), body.updatey() + body.updatetall() );
- }
- else
- {
- region.MarkAllDirty();
- }
-
- // Remove earlier paints for the same browser from the queue
- for ( int i = vecDeferredPaint.Count() - 1; i >= 0; --i )
- {
- if ( vecDeferredPaint[i]->m_iBrowser == iBrowser )
- {
- // Decode
- CHTMLProtoBufMsg<CMsgNeedsPaint> cmdMerge( eHTMLCommands_NeedsPaint );
- DbgVerify( cmdMerge.BDeserializeCrossProc( &vecDeferredPaint[i]->m_Buffer ) );
- CMsgNeedsPaint &bodyMerge = cmdMerge.Body();
-
- if ( body.browser_handle() == bodyMerge.browser_handle() )
- {
- ReleaseCommandBuffer( vecDeferredPaint[i] );
- vecDeferredPaint.Remove( i );
-
- // Merge update region
- if ( bodyMerge.updatewide() && bodyMerge.updatetall() )
- {
- region.MarkDirtyRect( bodyMerge.updatex(), bodyMerge.updatey(), bodyMerge.updatex() + bodyMerge.updatewide(), bodyMerge.updatey() + bodyMerge.updatetall() );
- }
- else
- {
- region.MarkAllDirty();
- }
-
- // Send response to the skipped paint update to free up the texture slot
- pCmd = GetFreeCommandBuffer( eHTMLCommands_NeedsPaintResponse, bodyMerge.browser_handle() );
- CHTMLProtoBufMsg<CMsgNeedsPaintResponse> cmdResponse( eHTMLCommands_NeedsPaintResponse );
- cmdResponse.Body().set_browser_handle( bodyMerge.browser_handle() );
- cmdResponse.Body().set_textureid( bodyMerge.textureid() );
- cmdResponse.SerializeCrossProc( &pCmd->m_Buffer );
- PushCommand( pCmd );
- }
- }
- }
-
- // Dispatch the merged update
- int idxBrowser = m_mapBrowsers.Find( body.browser_handle() );
- if ( idxBrowser != m_mapBrowsers.InvalidIndex() )
- {
- if ( m_mapBrowsers[idxBrowser] )
- {
- int updateWide = region.GetUpdateWide( body.wide() );
- int updateTall = region.GetUpdateTall( body.tall() );
- if ( updateWide != body.wide() || updateTall != body.tall() )
- {
- body.set_updatex( region.GetUpdateX( body.wide() ) );
- body.set_updatey( region.GetUpdateY( body.tall() ) );
- body.set_updatewide( updateWide );
- body.set_updatetall( updateTall );
- }
- else
- {
- body.clear_updatex();
- body.clear_updatey();
- body.clear_updatewide();
- body.clear_updatetall();
- }
- m_mapBrowsers[idxBrowser]->BrowserNeedsPaint( &body );
- }
- }
- }
-
- return bDidwork;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: set a cef cookie
-//-----------------------------------------------------------------------------
-void CHTMLController::SetWebCookie( const char *pchHostname, const char *pchKey, const char *pchValue, const char *pchPath, RTime32 nExpires )
-{
-#if !defined(WIN64) && !defined(STATIC_TIER0)
- ChromeSetWebCookie( pchHostname, pchKey, pchValue, pchPath, nExpires );
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: set the buildid to report
-//-----------------------------------------------------------------------------
-void CHTMLController::SetClientBuildID( uint64 ulBuildID )
-{
-#if !defined(WIN64) && !defined(STATIC_TIER0)
- ChromeSetClientBuildID( ulBuildID );
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: get the cef cookies for a url
-//-----------------------------------------------------------------------------
-void CHTMLController::GetWebCookiesForURL( CUtlString *pstrValue, const char *pchURL, const char *pchName )
-{
-#if !defined(WIN64) && !defined(STATIC_TIER0)
- ChromeGetWebCookiesForURL( pstrValue, pchURL, pchName );
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: true if any pending html message in the queue
-//-----------------------------------------------------------------------------
-bool CHTMLController::BHasPendingMessages()
-{
- return AccessHTMLWrapper().BHasPendingMessages();
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: tell the cef thread the frame rate to use if it changes
-//-----------------------------------------------------------------------------
-void CHTMLController::SetCefThreadTargetFrameRate( uint32 nFPS )
-{
- if ( nFPS != m_nCefTargetFrameRate )
- {
- m_nCefTargetFrameRate = nFPS;
- CHTMLProtoBufMsg<CMsgSetTargetFrameRate> cmd( eHTMLCommands_SetTargetFrameRate );
- cmd.Body().set_ntargetframerate( nFPS );
- HTMLCommandBuffer_t *pBuf = AccessHTMLWrapper().GetFreeCommandBuffer( eHTMLCommands_SetTargetFrameRate, -1 );
- cmd.SerializeCrossProc( &pBuf->m_Buffer );
- AccessHTMLWrapper().PushCommand( pBuf );
- }
-}
-
-#ifdef DBGFLAG_VALIDATE
-//-----------------------------------------------------------------------------
-// Purpose: validate mem
-//-----------------------------------------------------------------------------
-void CHTMLController::Validate( CValidator &validator, const char *pchName )
-{
- ChromeValidate( validator, "ChromeValidate" );
-
- validator.Push( "CHTMLController::ValidateStatics", NULL, pchName );
- ValidateObj( m_mapBrowserRequests );
- ValidateObj( m_mapBrowsers );
- validator.Pop();
-}
-
-bool CHTMLController::ChromeResumeFromValidate()
-{
- return ::ChromeResumeFromValidate();
-}
-
-bool CHTMLController::ChromePrepareForValidate()
-{
- return ::ChromePrepareForValidate();
-}
-#endif // DBGFLAG_VALIDATE
-
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Creates a HTML control +// +// $NoKeywords: $ +//=============================================================================// +#include "winlite.h" +#include "html_chrome.h" +#include "tier1/interface.h" +#include "reliabletimer.h" +#include "htmlmanager.h" + +#include "html/htmlprotobuf.h" +#include <html/ichromehtmlwrapper.h> + +//----------------------------------------------------------------------------- +// Purpose: owner object that gets responses from the CEF thread and dispatches them +//----------------------------------------------------------------------------- +class CHTMLController : public IHTMLChromeController +{ +public: + CHTMLController() { m_BrowserSerial = 0; m_nCefTargetFrameRate = 0; SetDefLessFunc( m_mapBrowserRequests ); SetDefLessFunc( m_mapBrowsers ); } + ~CHTMLController() {} + + bool Init( const char *pchHTMLCacheDir, const char *pchCookiePath ); + void Shutdown(); + + void SetWebCookie( const char *pchHostname, const char *pchKey, const char *pchValue, const char *pchPath, RTime32 nExpires ); + void GetWebCookiesForURL( CUtlString *pstrValue, const char *pchURL, const char *pchName ); + void SetClientBuildID( uint64 ulBuildID ); + + bool BHasPendingMessages(); + + void CreateBrowser( IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier ); + void RemoveBrowser( IHTMLResponses *pBrowser ); + bool RunFrame(); + + void WakeThread() { AccessHTMLWrapper().WakeThread(); } + HTMLCommandBuffer_t *GetFreeCommandBuffer( EHTMLCommands eCmd, int iBrowser ) { return AccessHTMLWrapper().GetFreeCommandBuffer( eCmd, iBrowser ); } + void PushCommand( HTMLCommandBuffer_t *pCmd ) { AccessHTMLWrapper().PushCommand( pCmd ); } + + + bool GetMainThreadCommand( HTMLCommandBuffer_t **pCmd ) { return AccessHTMLWrapper().GetMainThreadCommand( pCmd ); } + void ReleaseCommandBuffer( HTMLCommandBuffer_t *pCmd ) { AccessHTMLWrapper().ReleaseCommandBuffer( pCmd ); } + +#ifdef DBGFLAG_VALIDATE + void Validate( CValidator &validator, const char *pchName ); + bool ChromePrepareForValidate(); + bool ChromeResumeFromValidate(); +#endif + + void SetCefThreadTargetFrameRate( uint32 nFPS ); + +private: + // keeps track of outstanding browser create requests + CUtlMap< uint32, IHTMLResponses *, int > m_mapBrowserRequests; + // the next unique identifier to use when doing a browser create + uint32 m_BrowserSerial; + // the map of browser handles to our html panel objects, used for cef thread command dispatching + CUtlMap< uint32, IHTMLResponses *, int > m_mapBrowsers; + + int m_nCefTargetFrameRate; +}; + + +static CHTMLController s_HTMLController; +EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CHTMLController, IHTMLChromeController, CHROMEHTML_CONTROLLER_INTERFACE_VERSION, s_HTMLController ); + + +//----------------------------------------------------------------------------- +// Purpose: request the cef thread to make a new browser +//----------------------------------------------------------------------------- +void CHTMLController::CreateBrowser( IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier ) +{ + m_BrowserSerial++; + m_mapBrowserRequests.Insert( m_BrowserSerial, pBrowser ); + + CHTMLProtoBufMsg<CMsgBrowserCreate> cmd( eHTMLCommands_BrowserCreate ); + cmd.Body().set_request_id( m_BrowserSerial ); + cmd.Body().set_popup( bPopupWindow ); + cmd.Body().set_useragent( pchUserAgentIdentifier ); + HTMLCommandBuffer_t *pBuf = AccessHTMLWrapper().GetFreeCommandBuffer( eHTMLCommands_BrowserCreate, -1 ); + cmd.SerializeCrossProc( &pBuf->m_Buffer ); + AccessHTMLWrapper().PushCommand( pBuf ); +} + + +//----------------------------------------------------------------------------- +// Purpose: delete a browser we have +//----------------------------------------------------------------------------- +void CHTMLController::RemoveBrowser( IHTMLResponses *pBrowser ) +{ + + // pull ourselves from the browser handle list as we are doing away + FOR_EACH_MAP_FAST( m_mapBrowsers, i) + { + if ( m_mapBrowsers[i] == pBrowser ) + { + // tell the cef thread this browser is going away + CHTMLProtoBufMsg<CMsgBrowserRemove> cmd( eHTMLCommands_BrowserRemove ); + cmd.Body().set_browser_handle( pBrowser->BrowserGetIndex() ); + HTMLCommandBuffer_t *pBuf = AccessHTMLWrapper().GetFreeCommandBuffer( eHTMLCommands_BrowserRemove, pBrowser->BrowserGetIndex() ); + cmd.SerializeCrossProc( &pBuf->m_Buffer ); + AccessHTMLWrapper().PushCommand( pBuf ); + + // now kill it + m_mapBrowsers.RemoveAt( i ); + } + } + + // also remove us from pending list if in it + FOR_EACH_MAP_FAST( m_mapBrowserRequests, i) + { + if ( m_mapBrowserRequests[i] == pBrowser ) + m_mapBrowserRequests.RemoveAt( i ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: turn on the cef engine +//----------------------------------------------------------------------------- +bool CHTMLController::Init( const char *pchHTMLCacheDir, const char *pchCookiePath ) +{ +#if !defined(WIN64) && !defined(STATIC_TIER0) + ChromeInit( pchHTMLCacheDir, pchCookiePath ); +#endif + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: shutdown chrome +//----------------------------------------------------------------------------- +void CHTMLController::Shutdown() +{ +#if !defined(WIN64) && !defined(STATIC_TIER0) + ChromeShutdown(); +#endif +} + + + +// helper macro to dispatch messages from the cef thread +#define HTML_MSG_FUNC( eHTMLCommand, bodyType, commandFunc ) \ + case eHTMLCommand: \ +{ \ + CHTMLProtoBufMsg< bodyType > cmd( pCmd->m_eCmd ); \ + if ( !cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) ) \ +{ \ + bError = true; \ +} \ + else \ +{ \ + int idx = m_mapBrowsers.Find( cmd.BodyConst().browser_handle() ); \ + if ( idx != m_mapBrowsers.InvalidIndex() ) \ +{ \ + if ( m_mapBrowsers[idx] ) \ + m_mapBrowsers[idx]->commandFunc( &cmd.BodyConst() ); \ +} \ +} \ +} \ + break; \ + + +//----------------------------------------------------------------------------- +// Purpose: process any ipc responses we have pending +//----------------------------------------------------------------------------- +bool CHTMLController::RunFrame() +{ + VPROF_BUDGET( "CHTMLController::RunFrame", VPROF_BUDGETGROUP_TENFOOT ); + HTMLCommandBuffer_t *pCmd; + bool bError = false; + bool bDidwork = false; + + // Paint messages are dispatched last to avoid doing excessive work on + // the main thread when two paint messages have stacked up in the queue. + // This could be greatly optimized by doing atomic buffer swaps instead + // of pushing the paint updates through a queue, but this helps for now. + // -henryg + CUtlVector< HTMLCommandBuffer_t * > vecDeferredPaint; + + while( GetMainThreadCommand( &pCmd ) ) + { + bool bRelease = true; + bDidwork = true; + //Msg( "Got response %d\n", pCmd->m_eCmd ); + switch( pCmd->m_eCmd ) + { + default: + break; + case eHTMLCommands_BrowserCreateResponse: + { + CHTMLProtoBufMsg< CMsgBrowserCreateResponse > cmd( pCmd->m_eCmd ); + if ( !cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) ) + { + bError = true; + } + else + { + int idx = m_mapBrowserRequests.Find( cmd.BodyConst().request_id() ); + if ( idx != m_mapBrowserRequests.InvalidIndex() ) + { + m_mapBrowsers.Insert( cmd.BodyConst().browser_handle(), m_mapBrowserRequests[idx] ); + m_mapBrowserRequests[idx]->BrowserSetIndex( cmd.BodyConst().browser_handle() ); + m_mapBrowserRequests.RemoveAt( idx ); + } + } + } + break; + case eHTMLCommands_NeedsPaint: + { + bRelease = false; + vecDeferredPaint.AddToTail( pCmd ); + } + break; + + HTML_MSG_FUNC( eHTMLCommands_BrowserReady, CMsgBrowserReady, BrowserReady ); + HTML_MSG_FUNC( eHTMLCommands_StartRequest, CMsgStartRequest, BrowserStartRequest ); + HTML_MSG_FUNC( eHTMLCommands_URLChanged, CMsgURLChanged, BrowserURLChanged ); + HTML_MSG_FUNC( eHTMLCommands_FinishedRequest, CMsgFinishedRequest, BrowserFinishedRequest ); + HTML_MSG_FUNC( eHTMLCommands_ShowPopup, CMsgShowPopup, BrowserShowPopup ); + HTML_MSG_FUNC( eHTMLCommands_HidePopup, CMsgHidePopup, BrowserHidePopup ); + HTML_MSG_FUNC( eHTMLCommands_OpenNewTab, CMsgOpenNewTab, BrowserOpenNewTab ); + HTML_MSG_FUNC( eHTMLCommands_PopupHTMLWindow, CMsgPopupHTMLWindow, BrowserPopupHTMLWindow ); + HTML_MSG_FUNC( eHTMLCommands_SetHTMLTitle, CMsgSetHTMLTitle, BrowserSetHTMLTitle ); + HTML_MSG_FUNC( eHTMLCommands_LoadingResource, CMsgLoadingResource, BrowserLoadingResource ); + HTML_MSG_FUNC( eHTMLCommands_StatusText, CMsgStatusText, BrowserStatusText ); + HTML_MSG_FUNC( eHTMLCommands_SetCursor, CMsgSetCursor, BrowserSetCursor ); + HTML_MSG_FUNC( eHTMLCommands_FileLoadDialog, CMsgFileLoadDialog, BrowserFileLoadDialog ); + HTML_MSG_FUNC( eHTMLCommands_ShowToolTip, CMsgShowToolTip, BrowserShowToolTip ); + HTML_MSG_FUNC( eHTMLCommands_UpdateToolTip, CMsgUpdateToolTip, BrowserUpdateToolTip ); + HTML_MSG_FUNC( eHTMLCommands_HideToolTip, CMsgHideToolTip, BrowserHideToolTip ); + HTML_MSG_FUNC( eHTMLCommands_SearchResults, CMsgSearchResults, BrowserSearchResults ); + HTML_MSG_FUNC( eHTMLCommands_Close, CMsgClose, BrowserClose ); + HTML_MSG_FUNC( eHTMLCommands_GetZoomResponse, CMsgGetZoomResponse, BrowserGetZoomResponse ); + HTML_MSG_FUNC( eHTMLCommands_HorizontalScrollBarSizeResponse, CMsgHorizontalScrollBarSizeResponse, BrowserHorizontalScrollBarSizeResponse ); + HTML_MSG_FUNC( eHTMLCommands_VerticalScrollBarSizeResponse, CMsgVerticalScrollBarSizeResponse, BrowserVerticalScrollBarSizeResponse ); + HTML_MSG_FUNC( eHTMLCommands_LinkAtPositionResponse, CMsgLinkAtPositionResponse, BrowserLinkAtPositionResponse ); + HTML_MSG_FUNC( eHTMLCommands_ZoomToElementAtPositionResponse, CMsgZoomToElementAtPositionResponse, BrowserZoomToElementAtPositionResponse ); + HTML_MSG_FUNC( eHTMLCommands_JSAlert, CMsgJSAlert, BrowserJSAlert ); + HTML_MSG_FUNC( eHTMLCommands_JSConfirm, CMsgJSConfirm, BrowserJSConfirm ); + HTML_MSG_FUNC( eHTMLCommands_OpenSteamURL, CMsgOpenSteamURL, BrowserOpenSteamURL ); + HTML_MSG_FUNC( eHTMLCommands_CanGoBackandForward, CMsgCanGoBackAndForward, BrowserCanGoBackandForward ); + HTML_MSG_FUNC( eHTMLCommands_SizePopup, CMsgSizePopup, BrowserSizePopup ); + HTML_MSG_FUNC( eHTMLCommands_ScaleToValueResponse, CMsgScalePageToValueResponse, BrowserScalePageToValueResponse ); + HTML_MSG_FUNC( eHTMLCommands_RequestFullScreen, CMsgRequestFullScreen, BrowserRequestFullScreen ); + HTML_MSG_FUNC( eHTMLCommands_ExitFullScreen, CMsgExitFullScreen, BrowserExitFullScreen ); + HTML_MSG_FUNC( eHTMLCommands_GetCookiesForURLResponse, CMsgGetCookiesForURLResponse, BrowserGetCookiesForURLResponse ); + HTML_MSG_FUNC( eHTMLCommands_NodeGotFocus, CMsgNodeHasFocus, BrowserNodeGotFocus ); + HTML_MSG_FUNC( eHTMLCommands_SavePageToJPEGResponse, CMsgSavePageToJPEGResponse, BrowserSavePageToJPEGResponse ); + HTML_MSG_FUNC( eHTMLCommands_GetFocusedNodeValueResponse, CMsgFocusedNodeTextResponse, BrowserFocusedNodeValueResponse ); + } + if ( bError ) + { + Warning( "Failed to parse command %d", pCmd->m_eCmd ); + Assert( !"Bad Command" ); + } + if ( bRelease ) + { + ReleaseCommandBuffer( pCmd ); + } + } + + // Collapse deferred paints by browser ID and process them; the latest texture always + // has fully updated bits, we simply union its dirty rect with the skipped updates. + // Note: browser resizes always include a full dirty rect, we don't have to check here. + while ( vecDeferredPaint.Count() ) + { + // Pull the last paint off the queue + pCmd = vecDeferredPaint[ vecDeferredPaint.Count() - 1 ]; + int iBrowser = pCmd->m_iBrowser; + CHTMLProtoBufMsg<CMsgNeedsPaint> cmd( eHTMLCommands_NeedsPaint ); + DbgVerify( cmd.BDeserializeCrossProc( &pCmd->m_Buffer ) ); + ReleaseCommandBuffer( pCmd ); + vecDeferredPaint.Remove( vecDeferredPaint.Count() - 1 ); + + + CMsgNeedsPaint &body = cmd.Body(); + CChromeUpdateRegion region; + if ( body.updatewide() && body.updatetall() ) + { + region.MarkDirtyRect( body.updatex(), body.updatey(), body.updatex() + body.updatewide(), body.updatey() + body.updatetall() ); + } + else + { + region.MarkAllDirty(); + } + + // Remove earlier paints for the same browser from the queue + for ( int i = vecDeferredPaint.Count() - 1; i >= 0; --i ) + { + if ( vecDeferredPaint[i]->m_iBrowser == iBrowser ) + { + // Decode + CHTMLProtoBufMsg<CMsgNeedsPaint> cmdMerge( eHTMLCommands_NeedsPaint ); + DbgVerify( cmdMerge.BDeserializeCrossProc( &vecDeferredPaint[i]->m_Buffer ) ); + CMsgNeedsPaint &bodyMerge = cmdMerge.Body(); + + if ( body.browser_handle() == bodyMerge.browser_handle() ) + { + ReleaseCommandBuffer( vecDeferredPaint[i] ); + vecDeferredPaint.Remove( i ); + + // Merge update region + if ( bodyMerge.updatewide() && bodyMerge.updatetall() ) + { + region.MarkDirtyRect( bodyMerge.updatex(), bodyMerge.updatey(), bodyMerge.updatex() + bodyMerge.updatewide(), bodyMerge.updatey() + bodyMerge.updatetall() ); + } + else + { + region.MarkAllDirty(); + } + + // Send response to the skipped paint update to free up the texture slot + pCmd = GetFreeCommandBuffer( eHTMLCommands_NeedsPaintResponse, bodyMerge.browser_handle() ); + CHTMLProtoBufMsg<CMsgNeedsPaintResponse> cmdResponse( eHTMLCommands_NeedsPaintResponse ); + cmdResponse.Body().set_browser_handle( bodyMerge.browser_handle() ); + cmdResponse.Body().set_textureid( bodyMerge.textureid() ); + cmdResponse.SerializeCrossProc( &pCmd->m_Buffer ); + PushCommand( pCmd ); + } + } + } + + // Dispatch the merged update + int idxBrowser = m_mapBrowsers.Find( body.browser_handle() ); + if ( idxBrowser != m_mapBrowsers.InvalidIndex() ) + { + if ( m_mapBrowsers[idxBrowser] ) + { + int updateWide = region.GetUpdateWide( body.wide() ); + int updateTall = region.GetUpdateTall( body.tall() ); + if ( updateWide != body.wide() || updateTall != body.tall() ) + { + body.set_updatex( region.GetUpdateX( body.wide() ) ); + body.set_updatey( region.GetUpdateY( body.tall() ) ); + body.set_updatewide( updateWide ); + body.set_updatetall( updateTall ); + } + else + { + body.clear_updatex(); + body.clear_updatey(); + body.clear_updatewide(); + body.clear_updatetall(); + } + m_mapBrowsers[idxBrowser]->BrowserNeedsPaint( &body ); + } + } + } + + return bDidwork; +} + +//----------------------------------------------------------------------------- +// Purpose: set a cef cookie +//----------------------------------------------------------------------------- +void CHTMLController::SetWebCookie( const char *pchHostname, const char *pchKey, const char *pchValue, const char *pchPath, RTime32 nExpires ) +{ +#if !defined(WIN64) && !defined(STATIC_TIER0) + ChromeSetWebCookie( pchHostname, pchKey, pchValue, pchPath, nExpires ); +#endif +} + + +//----------------------------------------------------------------------------- +// Purpose: set the buildid to report +//----------------------------------------------------------------------------- +void CHTMLController::SetClientBuildID( uint64 ulBuildID ) +{ +#if !defined(WIN64) && !defined(STATIC_TIER0) + ChromeSetClientBuildID( ulBuildID ); +#endif +} + + +//----------------------------------------------------------------------------- +// Purpose: get the cef cookies for a url +//----------------------------------------------------------------------------- +void CHTMLController::GetWebCookiesForURL( CUtlString *pstrValue, const char *pchURL, const char *pchName ) +{ +#if !defined(WIN64) && !defined(STATIC_TIER0) + ChromeGetWebCookiesForURL( pstrValue, pchURL, pchName ); +#endif +} + + +//----------------------------------------------------------------------------- +// Purpose: true if any pending html message in the queue +//----------------------------------------------------------------------------- +bool CHTMLController::BHasPendingMessages() +{ + return AccessHTMLWrapper().BHasPendingMessages(); +} + + +//----------------------------------------------------------------------------- +// Purpose: tell the cef thread the frame rate to use if it changes +//----------------------------------------------------------------------------- +void CHTMLController::SetCefThreadTargetFrameRate( uint32 nFPS ) +{ + if ( nFPS != m_nCefTargetFrameRate ) + { + m_nCefTargetFrameRate = nFPS; + CHTMLProtoBufMsg<CMsgSetTargetFrameRate> cmd( eHTMLCommands_SetTargetFrameRate ); + cmd.Body().set_ntargetframerate( nFPS ); + HTMLCommandBuffer_t *pBuf = AccessHTMLWrapper().GetFreeCommandBuffer( eHTMLCommands_SetTargetFrameRate, -1 ); + cmd.SerializeCrossProc( &pBuf->m_Buffer ); + AccessHTMLWrapper().PushCommand( pBuf ); + } +} + +#ifdef DBGFLAG_VALIDATE +//----------------------------------------------------------------------------- +// Purpose: validate mem +//----------------------------------------------------------------------------- +void CHTMLController::Validate( CValidator &validator, const char *pchName ) +{ + ChromeValidate( validator, "ChromeValidate" ); + + validator.Push( "CHTMLController::ValidateStatics", NULL, pchName ); + ValidateObj( m_mapBrowserRequests ); + ValidateObj( m_mapBrowsers ); + validator.Pop(); +} + +bool CHTMLController::ChromeResumeFromValidate() +{ + return ::ChromeResumeFromValidate(); +} + +bool CHTMLController::ChromePrepareForValidate() +{ + return ::ChromePrepareForValidate(); +} +#endif // DBGFLAG_VALIDATE + + + |