From b62cb79c7e099129f635eebd29252a1fc919fa4b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 14 Nov 2008 16:48:07 +0000 Subject: [PATCH] Further work on experiment llmozlib/geko based embedded web browser --- examples/osgbrowser/CMakeLists.txt | 5 +- examples/osgbrowser/llembeddedbrowser.cpp | 446 +++++++------ .../osgbrowser/llembeddedbrowserwindow.cpp | 26 + examples/osgbrowser/llembeddedbrowserwindow.h | 3 + examples/osgbrowser/llmozlib2.cpp | 9 +- examples/osgbrowser/osgbrowser.cpp | 621 +++++++++++++++--- 6 files changed, 799 insertions(+), 311 deletions(-) diff --git a/examples/osgbrowser/CMakeLists.txt b/examples/osgbrowser/CMakeLists.txt index 7b74c3c71..3b262bf6e 100644 --- a/examples/osgbrowser/CMakeLists.txt +++ b/examples/osgbrowser/CMakeLists.txt @@ -17,7 +17,8 @@ ADD_DEFINITIONS(-DMOZILLA_INTERNAL_API) # MESSAGE("XUL_LIBRARIES = " ${XUL_LIBRARIES}) # MESSAGE("XUL_INCLUDE_DIRS = " ${XUL_INCLUDE_DIRS}) -INCLUDE_DIRECTORIES( +INCLUDE_DIRECTORIES( ${GLUT_INCLUDE_DIR} + ${GTK_INCLUDE_DIRS} ${GTKGL_INCLUDE_DIRS} ${XUL_INCLUDE_DIRS} /usr/include/xulrunner/locale /usr/include/xulrunner/view @@ -36,7 +37,7 @@ INCLUDE_DIRECTORIES( /usr/include/xulrunner/xulapp ) LINK_DIRECTORIES( ${XUL_LIB_DIRS}) -SET(TARGET_EXTERNAL_LIBRARIES ${XUL_LIBRARIES}) +SET(TARGET_EXTERNAL_LIBRARIES ${XUL_LIBRARIES} ${GLUT_glut_LIBRARY}) #### end var setup ### SETUP_EXAMPLE(osgbrowser) diff --git a/examples/osgbrowser/llembeddedbrowser.cpp b/examples/osgbrowser/llembeddedbrowser.cpp index 660fa1a95..e0da8b73d 100644 --- a/examples/osgbrowser/llembeddedbrowser.cpp +++ b/examples/osgbrowser/llembeddedbrowser.cpp @@ -38,11 +38,11 @@ // Windows specific switches #ifdef WIN32 - // appears to be required by LibXUL/Mozilla code to avoid crashes in debug versions of their code (undef'd at end of this file) - #ifdef _DEBUG - #define DEBUG 1 - #endif -#endif // WIN32 + // appears to be required by LibXUL/Mozilla code to avoid crashes in debug versions of their code (undef'd at end of this file) + #ifdef _DEBUG + #define DEBUG 1 + #endif +#endif // WIN32 #include @@ -50,9 +50,9 @@ #include "llembeddedbrowserwindow.h" #ifdef WIN32 - #pragma warning( disable : 4265 ) // "class has virtual functions, but destructor is not virtual" - #pragma warning( disable : 4291 ) // (no matching operator delete found; memory will not be freed if initialization throws an exception) -#endif // WIN32 + #pragma warning( disable : 4265 ) // "class has virtual functions, but destructor is not virtual" + #pragma warning( disable : 4291 ) // (no matching operator delete found; memory will not be freed if initialization throws an exception) +#endif // WIN32 #include "nsBuildID.h" #include "nsICacheService.h" @@ -75,8 +75,8 @@ LLEmbeddedBrowser* LLEmbeddedBrowser::sInstance = 0; //////////////////////////////////////////////////////////////////////////////// // LLEmbeddedBrowser::LLEmbeddedBrowser() : - mErrorNum( 0 ), - mNativeWindowHandle( 0 ) + mErrorNum( 0 ), + mNativeWindowHandle( 0 ) { } @@ -95,267 +95,281 @@ LLEmbeddedBrowser* LLEmbeddedBrowser::getInstance() sInstance = new LLEmbeddedBrowser; }; - return sInstance; + return sInstance; }; //////////////////////////////////////////////////////////////////////////////// // void LLEmbeddedBrowser::setLastError( int errorNumIn ) { - mErrorNum = errorNumIn; + mErrorNum = errorNumIn; } //////////////////////////////////////////////////////////////////////////////// // void LLEmbeddedBrowser::clearLastError() { - mErrorNum = 0x0000; + mErrorNum = 0x0000; } //////////////////////////////////////////////////////////////////////////////// // int LLEmbeddedBrowser::getLastError() { - return mErrorNum; + return mErrorNum; } //////////////////////////////////////////////////////////////////////////////// // std::string LLEmbeddedBrowser::getGREVersion() { - // take the string directly from Mozilla - return std::string( GRE_BUILD_ID ); + // take the string directly from Mozilla + return std::string( GRE_BUILD_ID ); } //////////////////////////////////////////////////////////////////////////////// // bool LLEmbeddedBrowser::init( std::string applicationDir, - std::string componentDir, - std::string profileDir, - void* nativeWindowHandleIn ) + std::string componentDir, + std::string profileDir, + void* nativeWindowHandleIn ) { - mNativeWindowHandle = nativeWindowHandleIn; + mNativeWindowHandle = nativeWindowHandleIn; + + std::cout<<"applicationDir "< applicationDirNative; - nsresult result = NS_NewLocalFile( applicationDirUTF16, PR_FALSE, getter_AddRefs( applicationDirNative ) ); - if ( NS_FAILED( result ) ) - { - setLastError( 0x1000 ); - return false; - }; + nsCOMPtr< nsILocalFile > applicationDirNative; + nsresult result = NS_NewLocalFile( applicationDirUTF16, PR_FALSE, getter_AddRefs( applicationDirNative ) ); + if ( NS_FAILED( result ) ) + { + std::cout<<"NS_NewLocalFile failed"< componentDirNative; - result = NS_NewLocalFile( componentDirUTF16 , PR_FALSE, getter_AddRefs( componentDirNative ) ); - if ( NS_FAILED( result ) ) - { - setLastError( 0x1001 ); - return false; - }; + nsCOMPtr< nsILocalFile > componentDirNative; + result = NS_NewLocalFile( componentDirUTF16 , PR_FALSE, getter_AddRefs( componentDirNative ) ); + if ( NS_FAILED( result ) ) + { + std::cout<<"NS_NewLocalFile failed 2"< profileDirNative; - result = NS_NewLocalFile( profileDirUTF16 , PR_TRUE, getter_AddRefs( profileDirNative ) ); - if ( NS_FAILED( result ) ) - { - setLastError( 0x1007 ); - return false; - }; + result = XRE_InitEmbedding( componentDirNative, applicationDirNative, nsnull, nsnull, 0 ); + if ( NS_FAILED( result ) ) + { + std::cout<<"XRE_InitEmbedding failed"< profileDirNative; + result = NS_NewLocalFile( profileDirUTF16 , PR_TRUE, getter_AddRefs( profileDirNative ) ); + if ( NS_FAILED( result ) ) + { + setLastError( 0x1007 ); + return false; + }; #if 0 - nsCOMPtr< nsProfileDirServiceProvider > locProvider; - NS_NewProfileDirServiceProvider( PR_TRUE, getter_AddRefs( locProvider ) ); - if ( ! locProvider ) - { - setLastError( 0x1003 ); - XRE_TermEmbedding(); - return PR_FALSE; - }; - result = locProvider->Register(); - if ( NS_FAILED( result ) ) - { - setLastError( 0x1004 ); - XRE_TermEmbedding(); - return PR_FALSE; - }; + nsCOMPtr< nsProfileDirServiceProvider > locProvider; + NS_NewProfileDirServiceProvider( PR_TRUE, getter_AddRefs( locProvider ) ); + if ( ! locProvider ) + { + setLastError( 0x1003 ); + XRE_TermEmbedding(); + return PR_FALSE; + }; + result = locProvider->Register(); + if ( NS_FAILED( result ) ) + { + setLastError( 0x1004 ); + XRE_TermEmbedding(); + return PR_FALSE; + }; - result = locProvider->SetProfileDir( profileDirNative ); - if ( NS_FAILED( result ) ) - { - setLastError( 0x1005 ); - XRE_TermEmbedding(); - return PR_FALSE; - }; + result = locProvider->SetProfileDir( profileDirNative ); + if ( NS_FAILED( result ) ) + { + setLastError( 0x1005 ); + XRE_TermEmbedding(); + return PR_FALSE; + }; #endif - nsCOMPtr pref = do_CreateInstance( NS_PREF_CONTRACTID ); - if ( pref ) - { - pref->SetBoolPref( "security.warn_entering_secure", PR_FALSE ); - pref->SetBoolPref( "security.warn_entering_weak", PR_FALSE ); - pref->SetBoolPref( "security.warn_leaving_secure", PR_FALSE ); - pref->SetBoolPref( "security.warn_submit_insecure", PR_FALSE ); - pref->SetBoolPref( "network.protocol-handler.warn-external-default", PR_FALSE ); - } - else - { - setLastError( 0x1006 ); - }; + nsCOMPtr pref = do_CreateInstance( NS_PREF_CONTRACTID ); + if ( pref ) + { + pref->SetBoolPref( "security.warn_entering_secure", PR_FALSE ); + pref->SetBoolPref( "security.warn_entering_weak", PR_FALSE ); + pref->SetBoolPref( "security.warn_leaving_secure", PR_FALSE ); + pref->SetBoolPref( "security.warn_submit_insecure", PR_FALSE ); + pref->SetBoolPref( "network.protocol-handler.warn-external-default", PR_FALSE ); + } + else + { + setLastError( 0x1006 ); + }; - // disable proxy by default - enableProxy( false, "", 0 ); + // disable proxy by default + enableProxy( false, "", 0 ); // Originally from Linux version but seems to help other platforms too - nsresult rv; - nsCOMPtr appShell; - NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); - appShell = do_CreateInstance(kAppShellCID, &rv); - if (!appShell) - { - setLastError( 0x1008 ); - return PR_FALSE; - } - sAppShell = appShell.get(); - NS_ADDREF(sAppShell); - sAppShell->Create(0, nsnull); - sAppShell->Spinup(); + nsresult rv; + nsCOMPtr appShell; + NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); + appShell = do_CreateInstance(kAppShellCID, &rv); + if (!appShell) + { + setLastError( 0x1008 ); + return PR_FALSE; + } + sAppShell = appShell.get(); + NS_ADDREF(sAppShell); + sAppShell->Create(0, nsnull); + sAppShell->Spinup(); - clearLastError(); + clearLastError(); - return true; + std::cout<<"LLEmbeddedBrowser::init() succeeded"< cacheService = do_GetService( NS_CACHESERVICE_CONTRACTID ); - if (! cacheService) - return false; + nsCOMPtr< nsICacheService > cacheService = do_GetService( NS_CACHESERVICE_CONTRACTID ); + if (! cacheService) + return false; - cacheService->EvictEntries( nsICache::STORE_ANYWHERE ); + cacheService->EvictEntries( nsICache::STORE_ANYWHERE ); - return true; + return true; } //////////////////////////////////////////////////////////////////////////////// // bool LLEmbeddedBrowser::enableProxy( bool proxyEnabledIn, std::string proxyHostNameIn, int proxyPortIn ) { - nsCOMPtr pref = do_CreateInstance( NS_PREF_CONTRACTID ); - if ( pref ) - { - if ( proxyEnabledIn ) - pref->SetIntPref( "network.proxy.type", 1 ); - else - pref->SetIntPref( "network.proxy.type", 0 ); + nsCOMPtr pref = do_CreateInstance( NS_PREF_CONTRACTID ); + if ( pref ) + { + if ( proxyEnabledIn ) + pref->SetIntPref( "network.proxy.type", 1 ); + else + pref->SetIntPref( "network.proxy.type", 0 ); - pref->SetCharPref( "network.proxy.ssl", proxyHostNameIn.c_str() ); - pref->SetIntPref( "network.proxy.ssl_port", proxyPortIn ); + pref->SetCharPref( "network.proxy.ssl", proxyHostNameIn.c_str() ); + pref->SetIntPref( "network.proxy.ssl_port", proxyPortIn ); - pref->SetCharPref( "network.proxy.ftp", proxyHostNameIn.c_str() ); - pref->SetIntPref( "network.proxy.ftp_port", proxyPortIn ); + pref->SetCharPref( "network.proxy.ftp", proxyHostNameIn.c_str() ); + pref->SetIntPref( "network.proxy.ftp_port", proxyPortIn ); - pref->SetCharPref( "network.proxy.gopher", proxyHostNameIn.c_str() ); - pref->SetIntPref( "network.proxy.gopher_port", proxyPortIn ); + pref->SetCharPref( "network.proxy.gopher", proxyHostNameIn.c_str() ); + pref->SetIntPref( "network.proxy.gopher_port", proxyPortIn ); - pref->SetCharPref( "network.proxy.http", proxyHostNameIn.c_str() ); - pref->SetIntPref( "network.proxy.http_port", proxyPortIn ); + pref->SetCharPref( "network.proxy.http", proxyHostNameIn.c_str() ); + pref->SetIntPref( "network.proxy.http_port", proxyPortIn ); - pref->SetBoolPref( "network.proxy.share_proxy_settings", true ); + pref->SetBoolPref( "network.proxy.share_proxy_settings", true ); - return true; - }; + return true; + }; - return false; + return false; } //////////////////////////////////////////////////////////////////////////////// // bool LLEmbeddedBrowser::enableCookies( bool enabledIn ) { - nsCOMPtr pref = do_CreateInstance( NS_PREF_CONTRACTID ); - if ( pref ) - { - if ( enabledIn ) - pref->SetIntPref( "network.cookie.cookieBehavior", 0 ); - else - pref->SetIntPref( "network.cookie.cookieBehavior", 2 ); + nsCOMPtr pref = do_CreateInstance( NS_PREF_CONTRACTID ); + if ( pref ) + { + if ( enabledIn ) + pref->SetIntPref( "network.cookie.cookieBehavior", 0 ); + else + pref->SetIntPref( "network.cookie.cookieBehavior", 2 ); - return true; - } + return true; + } - return false; + return false; } //////////////////////////////////////////////////////////////////////////////// // bool LLEmbeddedBrowser::clearAllCookies() { - nsCOMPtr< nsICookieManager > cookieManager = do_GetService( NS_COOKIEMANAGER_CONTRACTID ); - if ( ! cookieManager ) - return false; + nsCOMPtr< nsICookieManager > cookieManager = do_GetService( NS_COOKIEMANAGER_CONTRACTID ); + if ( ! cookieManager ) + return false; - cookieManager->RemoveAll(); + cookieManager->RemoveAll(); - return true; + return true; } //////////////////////////////////////////////////////////////////////////////// // bool LLEmbeddedBrowser::enablePlugins( bool enabledIn ) { - nsCOMPtr pref = do_CreateInstance( NS_PREF_CONTRACTID ); - if ( pref ) - { - if ( enabledIn ) - { - pref->SetBoolPref( "plugin.scan.plid.all", PR_TRUE ); - pref->SetBoolPref( "xpinstall-enabled", PR_TRUE ); - } - else - { - pref->SetBoolPref( "plugin.scan.plid.all", PR_FALSE ); - pref->SetBoolPref( "xpinstall-enabled", PR_FALSE ); - pref->SetBoolPref( "plugin.scan.4xPluginFolder", PR_FALSE ); - pref->SetCharPref( "plugin.scan.Quicktime", "20.0" ); - pref->SetCharPref( "plugin.scan.Acrobat", "99.0" ); - pref->SetCharPref( "plugin.scan.SunJRE", "99.0" ); - pref->SetCharPref( "plugin.scan.WindowsMediaPlayer", "99.0" ); - }; + nsCOMPtr pref = do_CreateInstance( NS_PREF_CONTRACTID ); + if ( pref ) + { + if ( enabledIn ) + { + pref->SetBoolPref( "plugin.scan.plid.all", PR_TRUE ); + pref->SetBoolPref( "xpinstall-enabled", PR_TRUE ); + } + else + { + pref->SetBoolPref( "plugin.scan.plid.all", PR_FALSE ); + pref->SetBoolPref( "xpinstall-enabled", PR_FALSE ); + pref->SetBoolPref( "plugin.scan.4xPluginFolder", PR_FALSE ); + pref->SetCharPref( "plugin.scan.Quicktime", "20.0" ); + pref->SetCharPref( "plugin.scan.Acrobat", "99.0" ); + pref->SetCharPref( "plugin.scan.SunJRE", "99.0" ); + pref->SetCharPref( "plugin.scan.WindowsMediaPlayer", "99.0" ); + }; - return true; - }; + return true; + }; - return false; + return false; } //////////////////////////////////////////////////////////////////////////////// // void LLEmbeddedBrowser::setBrowserAgentId( std::string idIn ) { - nsCOMPtr pref = do_CreateInstance( NS_PREF_CONTRACTID ); - if ( pref ) - { - pref->SetCharPref( "general.useragent.extra.* ", idIn.c_str() ); - }; + nsCOMPtr pref = do_CreateInstance( NS_PREF_CONTRACTID ); + if ( pref ) + { + pref->SetCharPref( "general.useragent.extra.* ", idIn.c_str() ); + }; } //////////////////////////////////////////////////////////////////////////////// @@ -364,43 +378,45 @@ LLEmbeddedBrowserWindow* LLEmbeddedBrowser::createBrowserWindow( int browserWidt { nsCOMPtr< nsIWebBrowserChrome > chrome; - LLEmbeddedBrowserWindow* newWin = new LLEmbeddedBrowserWindow(); - if ( ! newWin ) - { - return 0; - }; + LLEmbeddedBrowserWindow* newWin = new LLEmbeddedBrowserWindow(); + if ( ! newWin ) + { + std::cout<<"createBrowserWindow !newNew"<SetChromeFlags( nsIWebBrowserChrome::CHROME_ALL ); + newWin->SetChromeFlags( nsIWebBrowserChrome::CHROME_ALL ); - nsCOMPtr< nsIWebBrowser > newBrowser; + nsCOMPtr< nsIWebBrowser > newBrowser; - newWin->createBrowser( mNativeWindowHandle, browserWidthIn, browserHeightIn, getter_AddRefs( newBrowser ) ); - if ( ! newBrowser ) - { - return 0; - }; + newWin->createBrowser( mNativeWindowHandle, browserWidthIn, browserHeightIn, getter_AddRefs( newBrowser ) ); + if ( ! newBrowser ) + { + std::cout<<"createBrowserWindow !newBrowser"<setParent( this ); + newWin->setParent( this ); nsCOMPtr< nsIWebBrowser > newBrowser; chrome->GetWebBrowser( getter_AddRefs( newBrowser ) ); nsCOMPtr< nsIWebNavigation > webNav( do_QueryInterface ( newBrowser ) ); - webNav->LoadURI( NS_ConvertUTF8toUTF16( "about:blank" ).get(), nsIWebNavigation::LOAD_FLAGS_NONE, nsnull, nsnull, nsnull ); + webNav->LoadURI( NS_ConvertUTF8toUTF16( "about:blank" ).get(), nsIWebNavigation::LOAD_FLAGS_NONE, nsnull, nsnull, nsnull ); - clearLastError(); + clearLastError(); - return newWin; + return newWin; }; - setLastError( 0x2001 ); - return 0; + setLastError( 0x2001 ); + return 0; }; @@ -408,44 +424,44 @@ LLEmbeddedBrowserWindow* LLEmbeddedBrowser::createBrowserWindow( int browserWidt // bool LLEmbeddedBrowser::destroyBrowserWindow( LLEmbeddedBrowserWindow* browserWindowIn ) { - nsCOMPtr< nsIWebBrowser > webBrowser; - nsCOMPtr< nsIWebNavigation > webNavigation; + nsCOMPtr< nsIWebBrowser > webBrowser; + nsCOMPtr< nsIWebNavigation > webNavigation; - browserWindowIn->GetWebBrowser( getter_AddRefs( webBrowser ) ); - webNavigation = do_QueryInterface( webBrowser ); - if ( webNavigation ) - { - webNavigation->Stop( nsIWebNavigation::STOP_ALL ); - }; + browserWindowIn->GetWebBrowser( getter_AddRefs( webBrowser ) ); + webNavigation = do_QueryInterface( webBrowser ); + if ( webNavigation ) + { + webNavigation->Stop( nsIWebNavigation::STOP_ALL ); + }; - nsCOMPtr< nsIWebBrowser > browser = nsnull; - browserWindowIn->GetWebBrowser( getter_AddRefs( browser ) ); - nsCOMPtr< nsIBaseWindow > browserAsWin = do_QueryInterface( browser ); - if ( browserAsWin ) - { - browserAsWin->Destroy(); - }; + nsCOMPtr< nsIWebBrowser > browser = nsnull; + browserWindowIn->GetWebBrowser( getter_AddRefs( browser ) ); + nsCOMPtr< nsIBaseWindow > browserAsWin = do_QueryInterface( browser ); + if ( browserAsWin ) + { + browserAsWin->Destroy(); + }; - browserWindowIn->SetWebBrowser( nsnull ); + browserWindowIn->SetWebBrowser( nsnull ); - NS_RELEASE( browserWindowIn ); + NS_RELEASE( browserWindowIn ); - delete browserWindowIn; + delete browserWindowIn; - clearLastError(); + clearLastError(); - return true; + return true; } // Windows specific switches #ifdef WIN32 - #pragma warning( 3 : 4291 ) // (no matching operator delete found; memory will not be freed if initialization throws an exception) - #pragma warning( 3 : 4265 ) // "class has virtual functions, but destructor is not virtual" + #pragma warning( 3 : 4291 ) // (no matching operator delete found; memory will not be freed if initialization throws an exception) + #pragma warning( 3 : 4265 ) // "class has virtual functions, but destructor is not virtual" - // #define required by this file for LibXUL/Mozilla code to avoid crashes in their debug code - #ifdef _DEBUG - #undef DEBUG - #endif + // #define required by this file for LibXUL/Mozilla code to avoid crashes in their debug code + #ifdef _DEBUG + #undef DEBUG + #endif -#endif // WIN32 +#endif // WIN32 diff --git a/examples/osgbrowser/llembeddedbrowserwindow.cpp b/examples/osgbrowser/llembeddedbrowserwindow.cpp index 07a4bc5f9..50d0e4ad8 100644 --- a/examples/osgbrowser/llembeddedbrowserwindow.cpp +++ b/examples/osgbrowser/llembeddedbrowserwindow.cpp @@ -157,6 +157,8 @@ nsresult LLEmbeddedBrowserWindow::createBrowser( void* nativeWindowHandleIn, PRI mWebBrowser = do_CreateInstance( NS_WEBBROWSER_CONTRACTID, &rv ); if ( ! mWebBrowser ) { + std::cout<<"createBrowser ! mWebBrowser at start"< docShell = do_GetInterface( mWebBrowser ); if ( ! docShell ) return PR_FALSE; + std::cout<<"grabWindow() C"< presContext; @@ -603,6 +617,8 @@ unsigned char* LLEmbeddedBrowserWindow::grabWindow( int xIn, int yIn, int widthI if ( NS_FAILED( result ) || ( ! presContext ) ) return PR_FALSE; + std::cout<<"grabWindow() D"<GetViewManager(); if ( ! viewManager ) @@ -622,6 +638,8 @@ unsigned char* LLEmbeddedBrowserWindow::grabWindow( int xIn, int yIn, int widthI if ( rect.IsEmpty() ) return 0; + std::cout<<"grabWindow() E"<PixelsToTwips(); rect.width = NSIntPixelsToTwips( widthIn, p2t ); rect.height = NSIntPixelsToTwips( heightIn, p2t ); @@ -632,12 +650,16 @@ unsigned char* LLEmbeddedBrowserWindow::grabWindow( int xIn, int yIn, int widthI if ( NS_FAILED( result ) ) return 0; + std::cout<<"grabWindow() F"<GetDrawingSurface( &surface ); if ( ! surface ) return 0; + std::cout<<"grabWindow() G"<init( applicationDir, - componentDir, - profileDir, - nativeWindowHandleIn ); + componentDir, + profileDir, + nativeWindowHandleIn ); } //////////////////////////////////////////////////////////////////////////////// @@ -408,8 +408,11 @@ const unsigned char* LLMozLib::getBrowserWindowPixels( int browserWindowIdIn ) LLEmbeddedBrowserWindow* browserWindow = getBrowserWindowFromWindowId( browserWindowIdIn ); if ( browserWindow ) { + std::cout<<"Returning browserWindow->getPageBuffer() "<getPageBuffer(); }; + + std::cout<<"No browserWindow"< -class HttpImage : public osg::Image +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Linden Lab Inc. (http://lindenlab.com) code. + * + * The Initial Developer of the Original Code is: + * Callum Prentice (callum@ubrowser.com) + * + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Callum Prentice (callum@ubrowser.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. 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 MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include + +#include + +#include "llmozlib2.h" + +//////////////////////////////////////////////////////////////////////////////// +// Implementation of the test app - implemented as a class and derrives from +// the observer so we can catch events emitted by LLMozLib +// +class testGL : + public LLEmbeddedBrowserWindowObserver { - public: - - HttpImage() {} - - bool open(const std::string& filename) - { - osg::notify(osg::NOTICE)<<"open("<getVersion() << std::endl; + }; - int width = 1024; - int height = 1024; + //////////////////////////////////////////////////////////////////////////////// + // + void init( char* arg0 ) + { + // OpenGL initialization + glClearColor( 0.0f, 0.0f, 0.0f, 0.5f); + glEnable( GL_COLOR_MATERIAL ); + glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); + glEnable( GL_TEXTURE_2D ); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + glEnable( GL_CULL_FACE ); - allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE); - setPixelFormat(GL_BGRA); - setDataVariance(osg::Object::DYNAMIC); - setOrigin(osg::Image::TOP_LEFT); + // calculate texture size required (next power of two above browser window size + for ( mAppTextureWidth = 1; mAppTextureWidth < mBrowserWindowWidth; mAppTextureWidth <<= 1 ) + { + }; - return true; - } - - virtual void sendPointerEvent(int x, int y, int buttonMask) - { - osg::notify(osg::NOTICE)<<"sendPointerEvent("<init( applicationDir, componentDir, profileDir, getNativeWindowHandle() ); + + + mBrowserWindowId = LLMozLib::getInstance()->createBrowserWindow( mBrowserWindowWidth, mBrowserWindowHeight ); + + std::cout<<"after createBrowserWindow("<navigateTo( mBrowserWindowId, mHomeUrl ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void reset( void ) + { + // unhook observer + LLMozLib::getInstance()->remObserver( mBrowserWindowId, this ); + + // clean up + LLMozLib::getInstance()->reset(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void reshape( int widthIn, int heightIn ) + { + if ( heightIn == 0 ) + heightIn = 1; + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + + glViewport( 0, 0, widthIn, heightIn ); + glOrtho( 0.0f, widthIn, heightIn, 0.0f, -1.0f, 1.0f ); + + // we use these elsewhere so save + mAppWindowWidth = widthIn; + mAppWindowHeight = heightIn; + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + glutPostRedisplay(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void idle() + { + //std::cout<<"idle()"<grabBrowserWindow( mBrowserWindowId ); + + // lots of updates for smooth motion + glutPostRedisplay(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void display() + { + //std::cout<<"display() mBrowserWindowId = "<getBrowserWindowPixels( mBrowserWindowId ); + if ( pixels ) + { + + std::cout<<"Texture subload "<getBrowserRowSpan( mBrowserWindowId ) / LLMozLib::getInstance()->getBrowserDepth( mBrowserWindowId )<<", "<getBrowserRowSpan( mBrowserWindowId ) / LLMozLib::getInstance()->getBrowserDepth( mBrowserWindowId ), + mBrowserWindowHeight, + LLMozLib::getInstance()->getBrowserDepth( mBrowserWindowId ) == 3 ? GL_BGR_EXT : GL_BGRA_EXT, + GL_UNSIGNED_BYTE, + pixels ); + } + else + { + std::cout<<"No data to subload"<mouseDown( mBrowserWindowId, xIn, yIn ); + } + else + if ( state == GLUT_UP ) + { + // send event to LLMozLib + LLMozLib::getInstance()->mouseUp( mBrowserWindowId, xIn, yIn ); + + // this seems better than sending focus on mouse down (still need to improve this) + LLMozLib::getInstance()->focusBrowser( mBrowserWindowId, true ); + }; + }; + + // force a GLUT update + glutPostRedisplay(); + } + + //////////////////////////////////////////////////////////////////////////////// + // + void mouseMove( int xIn , int yIn ) + { + // texture is scaled to fit the screen so we scale mouse coords in the same way + xIn = ( xIn * mBrowserWindowWidth ) / mAppWindowWidth; + yIn = ( yIn * mBrowserWindowHeight ) / mAppWindowHeight; + + // send event to LLMozLib + LLMozLib::getInstance()->mouseMove( mBrowserWindowId, xIn, yIn ); + + // force a GLUT update + glutPostRedisplay(); + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void keyboard( unsigned char keyIn, int xIn, int yIn ) + { + if (keyIn=='a') + { + // go to the "home page" + LLMozLib::getInstance()->navigateTo( mBrowserWindowId, "http://www.linuxtoday.org" ); + + std::cout<<"new browse to"<keyPress( mBrowserWindowId, keyIn ); + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onPageChanged( const EventType& eventIn ) + { + // flag that an update is required - page grab happens in idle() so we don't stall + mNeedsUpdate = true; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onNavigateBegin( const EventType& eventIn ) + { + std::cout << "Event: begin navigation to " << eventIn.getEventUri() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onNavigateComplete( const EventType& eventIn ) + { + std::cout << "Event: end navigation to " << eventIn.getEventUri() << " with response status of " << eventIn.getIntValue() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onUpdateProgress( const EventType& eventIn ) + { + std::cout << "Event: progress value updated to " << eventIn.getIntValue() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onStatusTextChange( const EventType& eventIn ) + { + std::cout << "Event: status updated to " << eventIn.getStringValue() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onLocationChange( const EventType& eventIn ) + { + std::cout << "Event: location changed to " << eventIn.getStringValue() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onClickLinkHref( const EventType& eventIn ) + { + std::cout << "Event: clicked on link to " << eventIn.getStringValue() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + int getAppWindowWidth() + { + return mAppWindowWidth; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + int getAppWindowHeight() + { + return mAppWindowHeight; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + std::string getAppWindowName() + { + return mAppWindowName; + }; + + //////////////////////////////////////////////////////////////////////////////// + // + void* getNativeWindowHandle(); + + private: + int mAppWindowWidth; + int mAppWindowHeight; + int mBrowserWindowWidth; + int mBrowserWindowHeight; + int mAppTextureWidth; + int mAppTextureHeight; + GLuint mAppTexture; + int mBrowserWindowId; + std::string mAppWindowName; + std::string mHomeUrl; + bool mNeedsUpdate; }; -osg::Node* createInteractiveQuad(const osg::Vec3& origin, osg::Vec3& widthAxis, osg::Vec3& heightAxis, - osg::Image* image) +testGL* theApp; + +//////////////////////////////////////////////////////////////////////////////// +// +#ifdef _WINDOWS +void* testGL::getNativeWindowHandle() { - bool flip = image->getOrigin()==osg::Image::TOP_LEFT; + // My implementation of the embedded browser needs a native window handle + // Can't get this via GLUT so had to use this hack + return FindWindow( NULL, mAppWindowName.c_str() ); +} +#else - osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(origin, widthAxis, heightAxis, - 0.0f, flip ? 1.0f : 0.0f , 1.0f, flip ? 0.0f : 1.0f); +#include - osg::Texture2D* texture = new osg::Texture2D(image); - texture->setResizeNonPowerOfTwoHint(false); - texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR); - texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); - texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); - - pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0, - texture, - osg::StateAttribute::ON); - - pictureQuad->setEventCallback(new osgViewer::InteractiveImageHandler(image)); +void* testGL::getNativeWindowHandle() +{ + gtk_disable_setlocale(); + gtk_init(NULL, NULL); - osg::Geode* geode = new osg::Geode; - geode->addDrawable(pictureQuad); - - return geode; + GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_realize(win); + gtk_window_set_title(GTK_WINDOW(win), "Raw gecko window"); + + GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(win), GTK_NO_WINDOW); + + return win; +}; +#endif + +//////////////////////////////////////////////////////////////////////////////// +// +void glutReshape( int widthIn, int heightIn ) +{ + if ( theApp ) + theApp->reshape( widthIn, heightIn ); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutDisplay() +{ + if ( theApp ) + theApp->display(); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutIdle() +{ + if ( theApp ) + theApp->idle(); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutKeyboard( unsigned char keyIn, int xIn, int yIn ) +{ + if ( keyIn == 27 ) + { + if ( theApp ) + theApp->reset(); + + exit( 0 ); + }; + + if ( theApp ) + theApp->keyboard( keyIn, xIn, yIn ); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +void glutMouseMove( int xIn , int yIn ) +{ + if ( theApp ) + theApp->mouseMove( xIn, yIn ); } -int main(int argc,char** argv) +//////////////////////////////////////////////////////////////////////////////// +// +void glutMouseButton( int buttonIn, int stateIn, int xIn, int yIn ) { - - osg::ArgumentParser arguments(&argc, argv); - osgViewer::Viewer viewer(arguments); - - typedef std::list< osg::ref_ptr > Images; - Images images; - - for(int i=1; i httpImage= new HttpImage; - if (httpImage->open(arguments[i])) - { - images.push_back(httpImage.get()); - } - } - } - - bool xyPlane = false; - - osg::Group* group = new osg::Group; - - osg::Vec3 origin = osg::Vec3(0.0f,0.0f,0.0f); - for(Images::iterator itr = images.begin(); - itr != images.end(); - ++itr) - { - osg::Image* image = itr->get(); - float width = 1.0; - float height = float(image->t())/float(image->s()); - osg::Vec3 widthAxis = osg::Vec3(width,0.0f,0.0f); - osg::Vec3 heightAxis = xyPlane ? osg::Vec3(0.0f,height,0.0f) : osg::Vec3(0.0f,0.0f,height); - group->addChild(createInteractiveQuad(origin, widthAxis, heightAxis, image)); - - origin += widthAxis*1.1f; - } - - viewer.setSceneData(group); - - viewer.addEventHandler(new osgViewer::StatsHandler); - - //viewer.addEventHandler(new PageHandler); - - return viewer.run(); + if ( theApp ) + theApp->mouseButton( buttonIn, stateIn, xIn, yIn ); } +static void on_destroy(GtkWidget * widget, gpointer data) { + gtk_main_quit (); + +} + + +//////////////////////////////////////////////////////////////////////////////// +// +int main( int argc, char* argv[] ) +{ + + // implementation in a class so we can observer events + // means we need this painful GLUT <--> class shim... + theApp = new testGL; + + if ( theApp ) + { + glutInit( &argc, argv ); + glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB ); + + glutInitWindowPosition( 80, 0 ); + glutInitWindowSize( theApp->getAppWindowWidth(), theApp->getAppWindowHeight() ); + + glutCreateWindow( theApp->getAppWindowName().c_str() ); + + theApp->init( argv[ 0 ] ); + + glutKeyboardFunc( glutKeyboard ); + + glutMouseFunc( glutMouseButton ); + glutPassiveMotionFunc( glutMouseMove ); + glutMotionFunc( glutMouseMove ); + + glutDisplayFunc( glutDisplay ); + glutReshapeFunc( glutReshape ); + + glutIdleFunc( glutIdle ); + + glutMainLoop(); + + delete theApp; + }; + + return 0; +}