Code: Select all
/* ***** 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 Callum Prentice (callum@ubrowser.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 ***** */
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include "Irrlicht.h"
#include "llmozlib.h"
#include <iostream>
//#include "vld.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
//
class irrEmbeddedBrowser :
public LLEmbeddedBrowserWindowObserver, public irr::IEventReceiver
{
public:
irrEmbeddedBrowser( char* arg0, irr::video::IVideoDriver *irr_video_driver, irr::IrrlichtDevice* irr_device ) :
mIrrVideoDriver( irr_video_driver ),
mIrrDevice( irr_device ),
mBrowserWindowWidth( 1024 ), // width & height must be powers of 2 in this demo
mBrowserWindowHeight ( 1024 ), // until i figure out how to texture scale to fill poly
mNeedsUpdate( false )
{
// configure textures
mIrrVideoDriver->setTextureCreationFlag( irr::video::ETCF_CREATE_MIP_MAPS, false );
mIrrVideoDriver->setTextureCreationFlag( irr::video::ETCF_OPTIMIZED_FOR_QUALITY, true );
// mIrrVideoDriver->setTextureCreationFlag( irr::video::ETCF_ALWAYS_32_BIT, true );
// need a native window handle to pass to Mozilla - Irrlicht can give it to us..
void* native_window_handle = (void*)mIrrVideoDriver->getExposedVideoData().OpenGLWin32.HWnd;
// initialize, set up profile and open a browser window
std::string profileBaseDir = std::string( arg0 ).substr( 0, std::string( arg0 ).find_last_of("\\/") );
std::string profileName( "irrlichtProfile" );
LLMozLib::getInstance()->init( profileBaseDir, profileName );
mBrowserWindowId = LLMozLib::getInstance()->createBrowserWindow( native_window_handle, mBrowserWindowWidth, mBrowserWindowHeight );
// tell LLMozLib about the size of the browser window
LLMozLib::getInstance()->setSize( mBrowserWindowId, mBrowserWindowWidth, mBrowserWindowHeight );
// observer events that LLMozLib emits
LLMozLib::getInstance()->addObserver( mBrowserWindowId, this );
// got to the home page
LLMozLib::getInstance()->navigateTo( mBrowserWindowId, "http://www.google.com" );
// extremely sad hack - need to wait for browser surface to become valid
// fixed in most recent version of LLMozLib which will be released RSN
const unsigned char* pixels = LLMozLib::getInstance()->grabBrowserWindow( mBrowserWindowId );
while( ! pixels )
{
pixels = LLMozLib::getInstance()->grabBrowserWindow( mBrowserWindowId );
mIrrDevice->run();
};
// make an image
mIrrImage = mIrrVideoDriver->createImageFromData( irr::video::ECF_A8R8G8B8,
irr::core::dimension2d< irr::s32 >( mBrowserWindowWidth, mBrowserWindowHeight ),
(void*)pixels,
true);
// texture management
mIrrTexture = mIrrVideoDriver->addTexture( "LLMozLib", mIrrImage );
/*
// add a cube to display the texture
irr::scene::ISceneNode* node = mIrrDevice->getSceneManager()->addCubeSceneNode( 100 );
node->setPosition( irr::core::vector3df( 0,0,0 ) );
node->setMaterialTexture( 0, mIrrTexture );
node->setMaterialFlag( irr::video::EMF_LIGHTING, false );
irr::scene::ISceneNodeAnimator* anim = mIrrDevice->getSceneManager()->createRotationAnimator( irr::core::vector3df( 0.1f, 0, 0.13f ) );
node->addAnimator( anim );
anim->drop();
*/
node = mIrrDevice->getSceneManager()->addBillboardSceneNode(
mIrrDevice->getSceneManager()->getRootSceneNode(), irr::core::dimension2d<irr::f32>(mBrowserWindowWidth, mBrowserWindowHeight),
irr::core::vector3df(0, 0, 0), 202);
node->setPosition( irr::core::vector3df( 0,0,0 ) );
node->setMaterialTexture( 0, mIrrTexture );
node->setMaterialFlag( irr::video::EMF_LIGHTING, false );
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
~irrEmbeddedBrowser()
{
LLMozLib::getInstance()->remObserver( mBrowserWindowId, this );
LLMozLib::getInstance()->destroyBrowserWindow( mBrowserWindowId );
LLMozLib::getInstance()->reset();
LLMozLib::destroy();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
bool update()
{
// something changed on the page so it needs to be updated
if ( mNeedsUpdate )
{
// lock
irr::s32* texture = (irr::s32*)mIrrTexture->lock();
irr::s32* image = (irr::s32*)mIrrImage->lock();
// grab the page
LLMozLib::getInstance()->grabBrowserWindow( mBrowserWindowId );
// copy it from the image to the texture
memcpy( texture, image, LLMozLib::getInstance()->getBrowserRowSpan( mBrowserWindowId ) * LLMozLib::getInstance()->getBrowserHeight( mBrowserWindowId ) );
// flag that we updated it
mNeedsUpdate = false;
// unlock
mIrrTexture->unlock();
mIrrImage->unlock();
};
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
void navigateTo( std::string url )
{
LLMozLib::getInstance()->navigateTo( mBrowserWindowId, url );
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
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;
};
virtual bool OnEvent( irr::SEvent event )
{
if ( event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown == false )
{
if ( event.KeyInput.Key == '0' )
navigateTo( "http://www.google.com" );
if ( event.KeyInput.Key == '1' )
navigateTo( "http://www.irrlicht3d.org/" );
if ( event.KeyInput.Key == '2' )
navigateTo( "http://news.google.com" );
if ( event.KeyInput.Key == '3' )
navigateTo( "http://www.flickr.com/explore/interesting/7days/" );
if ( event.KeyInput.Key == '4' )
navigateTo( "http://www.faser.net/mab/chrome/content/mab.xul" );
if ( event.KeyInput.Key == '5' )
navigateTo( "http://developer.yahoo.com/yui/examples/slider/rgb2.html?mode=dist" );
if ( event.KeyInput.Key == 27 )
mIrrDevice->closeDevice();
}else if(event.EventType == irr::EET_MOUSE_INPUT_EVENT)
{
irr::video::S3DVertex* vertices = node->getVertices();
irr::core::position2d<irr::s32> positions[4];
irr::s32 xStart = 0;
irr::s32 xEnd = 0;
irr::s32 yStart = 0;
irr::s32 yEnd = 0;
for(irr::s32 i = 0; i < 4; i++)
{
positions[i] = mIrrDevice->getSceneManager()->getSceneCollisionManager()
->getScreenCoordinatesFrom3DPosition(vertices[i].Pos,
mIrrDevice->getSceneManager()->getActiveCamera());
if(i == 0)
{
xStart = positions[i].X;
xEnd = positions[i].X;
yStart = positions[i].Y;
yEnd = positions[i].Y;
}else{
if(positions[i].X >= xEnd)
{
xEnd = positions[i].X;
}
if(positions[i].Y <= xStart){
xStart = positions[i].X;
}
if(positions[i].Y >= yEnd)
{
yEnd = positions[i].Y;
}
if(positions[i].Y < yStart){
yStart = positions[i].Y;
}
}
}
// texture is scaled to fit the screen so we scale mouse coords in the same way
irr::s32 xIn = (event.MouseInput.X - xStart + 0.0f) / (xEnd - xStart)
* mBrowserWindowWidth;
irr::s32 yIn = (event.MouseInput.Y - yStart + 0.0f) / (yEnd - yStart)
* mBrowserWindowHeight;
if(event.MouseInput.Event == irr::EMIE_LMOUSE_PRESSED_DOWN)
{
// send event to LLMozLib
LLMozLib::getInstance()->mouseDown( mBrowserWindowId, xIn, yIn );
}else if(event.MouseInput.Event == irr::EMIE_LMOUSE_LEFT_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 );
}else if(event.MouseInput.Event == irr::EMIE_MOUSE_MOVED){
// send event to LLMozLib
LLMozLib::getInstance()->mouseMove( mBrowserWindowId, xIn, yIn );
}
}
return false;
};
private:
int mBrowserWindowId;
int mBrowserWindowWidth;
int mBrowserWindowHeight;
bool mNeedsUpdate;
irr::video::IVideoDriver *mIrrVideoDriver;
irr::video::IImage *mIrrImage;
irr::video::ITexture *mIrrTexture;
irr::IrrlichtDevice *mIrrDevice;
irr::scene::IBillboardSceneNode* node;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
//
int main( int argc, char *argv[] )
{
irr::IrrlichtDevice *theDevice = irr::createDevice( irr::video::EDT_OPENGL, irr::core::dimension2d< irr::s32 >( 800, 800 ), 32, false, false, false, 0 );
theDevice->setWindowCaption( L"irrLicht and LLMozlib" );
irr::video::IVideoDriver* driver = theDevice->getVideoDriver();
irrEmbeddedBrowser* theEmbeddedBrowser = new irrEmbeddedBrowser( argv[0], driver, theDevice );
theDevice->setEventReceiver(theEmbeddedBrowser);
irr::scene::ICameraSceneNode* cam = theDevice->getSceneManager()->addCameraSceneNode( 0, irr::core::vector3df( -100, -700, 100 ), irr::core::vector3df( 0, 0, 0 ) );
/*
irr::scene::ICameraSceneNode* cam = theDevice->getSceneManager()->addCameraSceneNodeFPS( 0, 100, 400, -1);
cam->setPosition(irr::core::vector3df( -100, 50, 100 ));
cam->setTarget(irr::core::vector3df( 0, 0, 0 ) );
*/
while ( theDevice->run() )
{
if(theDevice->isWindowActive()){
driver->beginScene( true, true, irr::video::SColor( 0xff, 0xa0, 0xa0, 0xc0 ) );
theDevice->getSceneManager()->drawAll();
theEmbeddedBrowser->update();
driver->endScene();
irr::core::stringw str = L" FPS: ";
str += driver->getFPS();
theDevice->setWindowCaption(str.c_str());
}
}
delete theEmbeddedBrowser;
//cam->drop();
theDevice->drop();
return 0;
}