From 094733def502cf9a30f360173ea68e8e7004604e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 19 Nov 2008 16:58:32 +0000 Subject: [PATCH] Refactored browser classes so that there is now a base class and reader writer. --- examples/osgbrowser/Browser.cpp | 51 ++ examples/osgbrowser/Browser.h | 60 ++ examples/osgbrowser/CMakeLists.txt | 6 + examples/osgbrowser/ReaderWriterUBrowser.cpp | 49 ++ examples/osgbrowser/UBrowser.cpp | 548 +++++++++++++++ examples/osgbrowser/UBrowser.h | 181 +++++ examples/osgbrowser/osgbrowser.cpp | 677 +------------------ 7 files changed, 901 insertions(+), 671 deletions(-) create mode 100644 examples/osgbrowser/Browser.cpp create mode 100644 examples/osgbrowser/Browser.h create mode 100644 examples/osgbrowser/ReaderWriterUBrowser.cpp create mode 100644 examples/osgbrowser/UBrowser.cpp create mode 100644 examples/osgbrowser/UBrowser.h diff --git a/examples/osgbrowser/Browser.cpp b/examples/osgbrowser/Browser.cpp new file mode 100644 index 000000000..709f5d8dd --- /dev/null +++ b/examples/osgbrowser/Browser.cpp @@ -0,0 +1,51 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include "Browser.h" + +#include + +using namespace osgWidget; + + +osg::ref_ptr& BrowserManager::instance() +{ + static osg::ref_ptr s_BrowserManager; + return s_BrowserManager; +} + +BrowserManager::BrowserManager() +{ + osg::notify(osg::NOTICE)<<"Constructing base BrowserManager"< +#include + +namespace osgWidget { + + +class BrowserImage; + +class BrowserManager : public osg::Object +{ + public: + + static osg::ref_ptr& instance(); + + virtual void init(const std::string& application); + + virtual BrowserImage* createBrowserImage(const std::string& url); + virtual BrowserImage* createBrowserImage(const std::string& url, int width, int height); + + protected: + + BrowserManager(); + BrowserManager(const BrowserManager& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) {} + virtual ~BrowserManager(); + + META_Object(osgWidget,BrowserManager) + + std::string _application; +}; + + +class BrowserImage : public osg::Image +{ + public: + + virtual void navigateTo(const std::string& url) = 0; + + +}; + + +} + +#endif diff --git a/examples/osgbrowser/CMakeLists.txt b/examples/osgbrowser/CMakeLists.txt index 24d29797d..8d0ff84ad 100644 --- a/examples/osgbrowser/CMakeLists.txt +++ b/examples/osgbrowser/CMakeLists.txt @@ -3,7 +3,10 @@ SET(TARGET_SRC llembeddedbrowserwindow.cpp llmozlib2.cpp nsProfileDirServiceProvider.cpp + Browser.cpp + UBrowser.cpp osgbrowser.cpp + ReaderWriterUBrowser.cpp ) SET(TARGET_H @@ -13,6 +16,8 @@ SET(TARGET_H nsProfileDirServiceProvider.h nsProfileLock.h nsProfileStringTypes.h + Browser.h + UBrowser.h ) ADD_DEFINITIONS(-DMOZILLA_INTERNAL_API) @@ -56,6 +61,7 @@ ELSE(WIN32 OR APPLE) ENDIF(WIN32 OR APPLE) +ADD_DEFINITIONS(-DXUL_DIR=${XUL_DIR}) #### end var setup ### SETUP_EXAMPLE(osgbrowser) diff --git a/examples/osgbrowser/ReaderWriterUBrowser.cpp b/examples/osgbrowser/ReaderWriterUBrowser.cpp new file mode 100644 index 000000000..190805113 --- /dev/null +++ b/examples/osgbrowser/ReaderWriterUBrowser.cpp @@ -0,0 +1,49 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include +#include +#include + +#include "UBrowser.h" + +class ReaderWriterUBrowser : public osgDB::ReaderWriter +{ + public: + + ReaderWriterUBrowser() + { + supportsExtension("browser","browser image"); + + osgWidget::BrowserManager::instance() = new UBrowserManager; + } + + virtual const char* className() const { return "Browser Reader/Writer"; } + + virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const + { + return readImage(file, options); + } + + virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const + { + std::string ext = osgDB::getLowerCaseFileExtension(file); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + + return osgWidget::BrowserManager::instance()->createBrowserImage(osgDB::getNameLessExtension(file)); + } +}; + +// now register with Registry to instantiate the above +// reader/writer. +REGISTER_OSGPLUGIN(ubrowser, ReaderWriterUBrowser) diff --git a/examples/osgbrowser/UBrowser.cpp b/examples/osgbrowser/UBrowser.cpp new file mode 100644 index 000000000..1abf09699 --- /dev/null +++ b/examples/osgbrowser/UBrowser.cpp @@ -0,0 +1,548 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include "UBrowser.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#ifdef _WINDOWS + #include +#elif defined(__APPLE__) + #include +#else + extern "C" { + #include + } +#endif + +////////////////////////////////////////////////////////////////////////// +// +// UBrowserManager implementation +// +UBrowserManager::UBrowserManager(): + _initialized(false), + _previousButtonMask(0) +{ +} + +UBrowserManager::~UBrowserManager() +{ + _thread->setDone(true); + + while(_thread->isRunning()) + { + OpenThreads::Thread::YieldCurrentThread(); + } + + _thread = 0; +} + +osgWidget::BrowserImage* UBrowserManager::createBrowserImage(const std::string& url, int width, int height) +{ + return new UBrowserImage(this, url, width, height); +} + +#if defined(_WINDOWS) +void* UBrowserManager::getNativeWindowHandle() +{ + if (_nativeWindowHandle) return _nativeWindowHandle; + + // My implementation of the embedded browser needs a native window handle + // Can't get this via GLUT so had to use this hack + _nativeWindowHandle = FindWindow( NULL, _appWindowName.c_str() ); + + return _nativeWindowHandle; +} + +#elif defined(__APPLE__) +void* UBrowserManager::getNativeWindowHandle() +{ + if (_nativeWindowHandle) return _nativeWindowHandle; + + // Create a window just for this purpose. + Rect window_rect = {100, 100, 200, 200}; + + _nativeWindowHandle = (void*) NewCWindow( + NULL, + &window_rect, + "\p", + false, // Create the window invisible. + zoomDocProc, // Window with a grow box and a zoom box + kLastWindowOfClass, // create it behind other windows + false, // no close box + 0); + } + + return _nativeWindowHandle; +} +#else +void* UBrowserManager::getNativeWindowHandle() +{ + if (_nativeWindowHandle) return _nativeWindowHandle; + + gtk_disable_setlocale(); + gtk_init(NULL, NULL); + + GtkWidget *win = gtk_window_new(GTK_WINDOW_POPUP); + // Why a layout widget? A MozContainer would be ideal, but + // it involves exposing Mozilla headers to mozlib-using apps. + // A layout widget with a GtkWindow parent has the desired + // properties of being plain GTK, having a window, and being + // derived from a GtkContainer. + GtkWidget *rtnw = gtk_layout_new(NULL, NULL); + gtk_container_add(GTK_CONTAINER(win), rtnw); + gtk_widget_realize(rtnw); + GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(rtnw), GTK_NO_WINDOW); + + _nativeWindowHandle = rtnw; + + return _nativeWindowHandle; +} +#endif + +struct InitOperation : public osg::Operation +{ + InitOperation(): + Operation("init",false) {} + + /** Override the standard Operation operator and dynamic cast object to a GraphicsContext, + * on success call operation()(GraphicsContext*).*/ + virtual void operator () (osg::Object* object) + { + UBrowserManager* ubrowserManager = dynamic_cast(object); + + // create a single browser window and set things up. + std::string applicationDir = osgDB::getFilePath(ubrowserManager->getApplication()); + if (applicationDir.empty()) applicationDir = osgDB::getRealPath("."); + else applicationDir = osgDB::getRealPath(applicationDir); + + osg::notify(osg::NOTICE)<<"XUL_DIR = "<<#XUL_DIR<init( applicationDir, componentDir, profileDir, ubrowserManager->getNativeWindowHandle() ); + + // append details to agent string + LLMozLib::getInstance()->setBrowserAgentId( ubrowserManager->getApplication() ); + } + +}; + +struct UpdateOperation : public osg::Operation +{ + UpdateOperation(): + osg::Operation("update",true) {} + + virtual void operator () (osg::Object* object) + { + UBrowserManager* ubrowserManager = dynamic_cast(object); + + // osg::notify(osg::NOTICE)<<"Update"<_ubrowserImageList.empty()) + { + // osg::notify(osg::NOTICE)<<"Nothing to do"< > RefImageList; + RefImageList images; + + { + OpenThreads::ScopedLock lock(ubrowserManager->_ubrowserImageListMutex); + std::copy(ubrowserManager->_ubrowserImageList.begin(), + ubrowserManager->_ubrowserImageList.end(), + std::back_inserter(images)); + } + + for(RefImageList::iterator itr = images.begin(); + itr != images.end(); + ++itr) + { + update(itr->get()); + } + + // osg::notify(osg::NOTICE)<<"complted Update"<getBrowserWindowId(); + + if (id==0) + { + int width = image->s(); + int height = image->t(); + + osg::notify(osg::INFO)<<"Constructing browser window for first time, width = "<getBrowserWindowId(); + + // send event to LLMozLib + if (_buttonDelta>0) + { + LLMozLib::getInstance()->mouseDown( id, _x, _y ); + } + else if (_buttonDelta<0) + { + LLMozLib::getInstance()->mouseUp( id, _x, _y ); + + // this seems better than sending focus on mouse down (still need to improve this) + LLMozLib::getInstance()->focusBrowser( id, true ); + } + else + { + // send event to LLMozLib + LLMozLib::getInstance()->mouseMove( id, _x, _y ); + } + + } + + osg::ref_ptr _image; + int _x; + int _y; + int _buttonDelta; +}; + +void UBrowserManager::sendPointerEvent(UBrowserImage* image, int x, int y, int buttonMask) +{ + int deltaButton = (buttonMask&1) - (_previousButtonMask&1); + _previousButtonMask = buttonMask; + + _thread->add(new PointerEventOperation(image, x, y, deltaButton)); +} + + +struct KeyEventOperation : public osg::Operation +{ + KeyEventOperation(UBrowserImage* image, int key, bool isUnicode): + osg::Operation("key event",false), + _image(image), + _key(key), + _isUnicode(isUnicode) {} + + virtual void operator () (osg::Object* object) + { + int id = _image->getBrowserWindowId(); + if (_isUnicode) LLMozLib::getInstance()->unicodeInput( id, _key ); + else LLMozLib::getInstance()->keyPress( id, _key ); + } + + osg::ref_ptr _image; + int _key; + bool _isUnicode; +}; + +void UBrowserManager::sendKeyEvent(UBrowserImage* image, int key, bool keyDown) +{ + if (!keyDown) return; + + KeyMap::const_iterator itr = _keyMap.find(key); + if (_keyMap.find(key)==_keyMap.end()) _thread->add(new KeyEventOperation(image, key, true)); + else _thread->add(new KeyEventOperation(image, itr->second, false)); + +} + + +struct NavigateToOperation : public osg::Operation +{ + NavigateToOperation(UBrowserImage* image, const std::string& url): + osg::Operation("key event",false), + _image(image), + _url(url) {} + + virtual void operator () (osg::Object* object) + { + int id = _image->getBrowserWindowId(); + LLMozLib::getInstance()->navigateTo( id, _url ); + } + + osg::ref_ptr _image; + std::string _url; +}; + +void UBrowserManager::navigateTo(UBrowserImage* image, const std::string& url) +{ + _thread->add(new NavigateToOperation(image, url)); +} + +//////////////////////////////////////////////////////////////////////////////////// +// +// UBrowser implementation + +UBrowserImage::UBrowserImage(UBrowserManager* manager, const std::string& homeURL, int width, int height): + _browserWindowId(0), + _needsUpdate(true) +{ + _manager = manager; + + GLint internalFormat = GL_RGB; + GLenum pixelFormat = GL_BGR_EXT; + + setImage(width,height,1, internalFormat, pixelFormat, GL_UNSIGNED_BYTE, + 0, + osg::Image::NO_DELETE); + + setDataVariance(osg::Object::DYNAMIC); + setOrigin(osg::Image::TOP_LEFT); + + _homeURL = homeURL; + + manager->registerUBrowserImage(this); + +} + +UBrowserImage::~UBrowserImage() +{ + _manager->unregisterUBrowserImage(this); +} + +void UBrowserImage::sendPointerEvent(int x, int y, int buttonMask) +{ + _manager->sendPointerEvent(this, x, y, buttonMask); +} + +void UBrowserImage::sendKeyEvent(int key, bool keyDown) +{ + _manager->sendKeyEvent(this, key, keyDown); +} + +void UBrowserImage::navigateTo(const std::string& url) +{ + _manager->navigateTo(this, url); +} + diff --git a/examples/osgbrowser/UBrowser.h b/examples/osgbrowser/UBrowser.h new file mode 100644 index 000000000..e18dba8a0 --- /dev/null +++ b/examples/osgbrowser/UBrowser.h @@ -0,0 +1,181 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef UBROWSER_H +#define UBROWSER_H + +#include "Browser.h" + +#include + +#include + +#include +#include "llmozlib2.h" + +class UBrowserImage; + +////////////////////////////////////////////////////////////////////////// +// +// UBrowserManager interface +// +class UBrowserManager : public osgWidget::BrowserManager +{ + public: + + UBrowserManager(); + + virtual void init(const std::string& application); + + virtual osgWidget::BrowserImage* createBrowserImage(const std::string& url, int width, int height); + + public: + + void* getNativeWindowHandle(); + + const std::string& getApplication() const { return _application; } + + void registerUBrowserImage(UBrowserImage* image) + { + OpenThreads::ScopedLock lock(_ubrowserImageListMutex); + _ubrowserImageList.push_back(image); + } + + void unregisterUBrowserImage(UBrowserImage* image) + { + OpenThreads::ScopedLock lock(_ubrowserImageListMutex); + UBrowserImageList::iterator itr = std::find(_ubrowserImageList.begin(), _ubrowserImageList.end(), image); + if (itr != _ubrowserImageList.end()) _ubrowserImageList.erase(itr); + } + + void sendKeyEvent(UBrowserImage* image, int key, bool keyDown); + + void sendPointerEvent(UBrowserImage* image, int x, int y, int buttonMask); + + void navigateTo(UBrowserImage* image, const std::string& page); + + typedef std::list< UBrowserImage* > UBrowserImageList; + + OpenThreads::Mutex _ubrowserImageListMutex; + UBrowserImageList _ubrowserImageList; + + protected: + + UBrowserManager(const UBrowserManager& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) {} + + virtual ~UBrowserManager(); + + META_Object(osgWidget,UBrowserManager) + + void setUpKeyMap(); + int convertToXULKey(int key) const; + + bool _initialized; + bool _done; + + std::string _application; + void* _nativeWindowHandle; + + typedef std::map KeyMap; + KeyMap _keyMap; + + int _previousButtonMask; + + osg::ref_ptr _thread; +}; + +//////////////////////////////////////////////////////////////////////////////////// +// +// UBrowser interface +class UBrowserImage : public osgWidget::BrowserImage, public LLEmbeddedBrowserWindowObserver +{ + public: + + UBrowserImage(UBrowserManager* manager, const std::string& homeURL, int width, int height); + + + const std::string& getHomeURL() const { return _homeURL; } + + virtual void sendPointerEvent(int x, int y, int buttonMask); + + virtual void sendKeyEvent(int key, bool keyDown); + + virtual void navigateTo(const std::string& url); + + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onPageChanged( const EventType& eventIn ) + { + // flag that an update is required - page grab happens in idle() so we don't stall + osg::notify(osg::NOTICE) << "Event: onPageChanged " << eventIn.getEventUri() << std::endl; + _needsUpdate = true; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onNavigateBegin( const EventType& eventIn ) + { + osg::notify(osg::NOTICE) << "Event: begin navigation to " << eventIn.getEventUri() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onNavigateComplete( const EventType& eventIn ) + { + osg::notify(osg::NOTICE) << "Event: end navigation to " << eventIn.getEventUri() << " with response status of " << eventIn.getIntValue() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onUpdateProgress( const EventType& eventIn ) + { + osg::notify(osg::NOTICE) << "Event: progress value updated to " << eventIn.getIntValue() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onStatusTextChange( const EventType& eventIn ) + { + osg::notify(osg::NOTICE) << "Event: status updated to " << eventIn.getStringValue() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onLocationChange( const EventType& eventIn ) + { + osg::notify(osg::NOTICE) << "Event: location changed to " << eventIn.getStringValue() << std::endl; + }; + + //////////////////////////////////////////////////////////////////////////////// + // virtual + void onClickLinkHref( const EventType& eventIn ) + { + osg::notify(osg::NOTICE) << "Event: clicked on link to " << eventIn.getStringValue() << std::endl; + }; + + void setBrowserWindowId(int id) { _browserWindowId = id; } + int getBrowserWindowId() const { return _browserWindowId; } + + osg::ref_ptr _manager; + + protected: + + virtual ~UBrowserImage(); + + int _browserWindowId; + bool _needsUpdate; + std::string _homeURL; +}; + +#endif diff --git a/examples/osgbrowser/osgbrowser.cpp b/examples/osgbrowser/osgbrowser.cpp index c149d83d3..2e707c3e7 100644 --- a/examples/osgbrowser/osgbrowser.cpp +++ b/examples/osgbrowser/osgbrowser.cpp @@ -16,674 +16,7 @@ #include "llmozlib2.h" -class UBrowserImage; - -#ifdef _WINDOWS - #include -#elif defined(__APPLE__) - #include -#else - extern "C" { - #include - } -#endif - -////////////////////////////////////////////////////////////////////////// -// -// UBrowserManager interface -// -class UBrowserManager : public osg::Object -{ - public: - - - static osg::ref_ptr& instance(); - - void init(const std::string& application); - - void* getNativeWindowHandle(); - - const std::string& getApplication() const { return _application; } - - void registerUBrowserImage(UBrowserImage* image) - { - OpenThreads::ScopedLock lock(_ubrowserImageListMutex); - _ubrowserImageList.push_back(image); - } - - void unregisterUBrowserImage(UBrowserImage* image) - { - OpenThreads::ScopedLock lock(_ubrowserImageListMutex); - UBrowserImageList::iterator itr = std::find(_ubrowserImageList.begin(), _ubrowserImageList.end(), image); - if (itr != _ubrowserImageList.end()) _ubrowserImageList.erase(itr); - } - - void sendKeyEvent(UBrowserImage* image, int key, bool keyDown); - - void sendPointerEvent(UBrowserImage* image, int x, int y, int buttonMask); - - void navigateTo(UBrowserImage* image, const std::string& page); - - typedef std::list< UBrowserImage* > UBrowserImageList; - - OpenThreads::Mutex _ubrowserImageListMutex; - UBrowserImageList _ubrowserImageList; - - protected: - - UBrowserManager(); - - UBrowserManager(const UBrowserManager& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) {} - - virtual ~UBrowserManager(); - - META_Object(osgWidget,UBrowserManager) - - void setUpKeyMap(); - int convertToXULKey(int key) const; - - bool _initialized; - bool _done; - - std::string _application; - void* _nativeWindowHandle; - - typedef std::map KeyMap; - KeyMap _keyMap; - - int _previousButtonMask; - - osg::ref_ptr _thread; -}; - -//////////////////////////////////////////////////////////////////////////////////// -// -// UBrowser interface -class UBrowserImage : public osg::Image, public LLEmbeddedBrowserWindowObserver -{ - public: - - UBrowserImage(const std::string& homeURL, int width, int height); - - - const std::string& getHomeURL() const { return _homeURL; } - - virtual void sendPointerEvent(int x, int y, int buttonMask); - - virtual void sendKeyEvent(int key, bool keyDown); - - void navigateTo(const std::string& page); - - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onPageChanged( const EventType& eventIn ) - { - // flag that an update is required - page grab happens in idle() so we don't stall - osg::notify(osg::NOTICE) << "Event: onPageChanged " << eventIn.getEventUri() << std::endl; - _needsUpdate = true; - }; - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onNavigateBegin( const EventType& eventIn ) - { - osg::notify(osg::NOTICE) << "Event: begin navigation to " << eventIn.getEventUri() << std::endl; - }; - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onNavigateComplete( const EventType& eventIn ) - { - osg::notify(osg::NOTICE) << "Event: end navigation to " << eventIn.getEventUri() << " with response status of " << eventIn.getIntValue() << std::endl; - }; - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onUpdateProgress( const EventType& eventIn ) - { - osg::notify(osg::NOTICE) << "Event: progress value updated to " << eventIn.getIntValue() << std::endl; - }; - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onStatusTextChange( const EventType& eventIn ) - { - osg::notify(osg::NOTICE) << "Event: status updated to " << eventIn.getStringValue() << std::endl; - }; - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onLocationChange( const EventType& eventIn ) - { - osg::notify(osg::NOTICE) << "Event: location changed to " << eventIn.getStringValue() << std::endl; - }; - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onClickLinkHref( const EventType& eventIn ) - { - osg::notify(osg::NOTICE) << "Event: clicked on link to " << eventIn.getStringValue() << std::endl; - }; - - void setBrowserWindowId(int id) { _browserWindowId = id; } - int getBrowserWindowId() const { return _browserWindowId; } - - protected: - - virtual ~UBrowserImage(); - - int _browserWindowId; - bool _needsUpdate; - std::string _homeURL; -}; - -////////////////////////////////////////////////////////////////////////// -// -// UBrowserManager implementation -// -UBrowserManager::UBrowserManager(): - _initialized(false), - _previousButtonMask(0) -{ -} - -UBrowserManager::~UBrowserManager() -{ - _thread->setDone(true); - - while(_thread->isRunning()) - { - OpenThreads::Thread::YieldCurrentThread(); - } - - _thread = 0; -} - -osg::ref_ptr& UBrowserManager::instance() -{ - static osg::ref_ptr s_UBrowserManager = new UBrowserManager; - return s_UBrowserManager; -} - -#if defined(_WINDOWS) -void* UBrowserManager::getNativeWindowHandle() -{ - if (_nativeWindowHandle) return _nativeWindowHandle; - - // My implementation of the embedded browser needs a native window handle - // Can't get this via GLUT so had to use this hack - _nativeWindowHandle = FindWindow( NULL, _appWindowName.c_str() ); - - return _nativeWindowHandle; -} - -#elif defined(__APPLE__) -void* UBrowserManager::getNativeWindowHandle() -{ - if (_nativeWindowHandle) return _nativeWindowHandle; - - // Create a window just for this purpose. - Rect window_rect = {100, 100, 200, 200}; - - _nativeWindowHandle = (void*) NewCWindow( - NULL, - &window_rect, - "\p", - false, // Create the window invisible. - zoomDocProc, // Window with a grow box and a zoom box - kLastWindowOfClass, // create it behind other windows - false, // no close box - 0); - } - - return _nativeWindowHandle; -} -#else -void* UBrowserManager::getNativeWindowHandle() -{ - if (_nativeWindowHandle) return _nativeWindowHandle; - - gtk_disable_setlocale(); - gtk_init(NULL, NULL); - - GtkWidget *win = gtk_window_new(GTK_WINDOW_POPUP); - // Why a layout widget? A MozContainer would be ideal, but - // it involves exposing Mozilla headers to mozlib-using apps. - // A layout widget with a GtkWindow parent has the desired - // properties of being plain GTK, having a window, and being - // derived from a GtkContainer. - GtkWidget *rtnw = gtk_layout_new(NULL, NULL); - gtk_container_add(GTK_CONTAINER(win), rtnw); - gtk_widget_realize(rtnw); - GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(rtnw), GTK_NO_WINDOW); - - _nativeWindowHandle = rtnw; - - return _nativeWindowHandle; -} -#endif - -struct InitOperation : public osg::Operation -{ - InitOperation(): - Operation("init",false) {} - - /** Override the standard Operation operator and dynamic cast object to a GraphicsContext, - * on success call operation()(GraphicsContext*).*/ - virtual void operator () (osg::Object* object) - { - UBrowserManager* ubrowserManager = dynamic_cast(object); - - // create a single browser window and set things up. - std::string applicationDir = osgDB::getFilePath(ubrowserManager->getApplication()); - if (applicationDir.empty()) applicationDir = osgDB::getRealPath("."); - else applicationDir = osgDB::getRealPath(applicationDir); - - std::string componentDir = "/usr/lib/xulrunner"; - std::string profileDir = applicationDir + "/" + "testGL_profile"; - LLMozLib::getInstance()->init( applicationDir, componentDir, profileDir, ubrowserManager->getNativeWindowHandle() ); - - // append details to agent string - LLMozLib::getInstance()->setBrowserAgentId( ubrowserManager->getApplication() ); - } - -}; - -struct UpdateOperation : public osg::Operation -{ - UpdateOperation(): - osg::Operation("update",true) {} - - virtual void operator () (osg::Object* object) - { - UBrowserManager* ubrowserManager = dynamic_cast(object); - - // osg::notify(osg::NOTICE)<<"Update"<_ubrowserImageList.empty()) - { - // osg::notify(osg::NOTICE)<<"Nothing to do"< > RefImageList; - RefImageList images; - - { - OpenThreads::ScopedLock lock(ubrowserManager->_ubrowserImageListMutex); - std::copy(ubrowserManager->_ubrowserImageList.begin(), - ubrowserManager->_ubrowserImageList.end(), - std::back_inserter(images)); - } - - for(RefImageList::iterator itr = images.begin(); - itr != images.end(); - ++itr) - { - update(itr->get()); - } - - // osg::notify(osg::NOTICE)<<"complted Update"<getBrowserWindowId(); - - if (id==0) - { - int width = image->s(); - int height = image->t(); - - osg::notify(osg::INFO)<<"Constructing browser window for first time, width = "<getBrowserWindowId(); - - // send event to LLMozLib - if (_buttonDelta>0) - { - LLMozLib::getInstance()->mouseDown( id, _x, _y ); - } - else if (_buttonDelta<0) - { - LLMozLib::getInstance()->mouseUp( id, _x, _y ); - - // this seems better than sending focus on mouse down (still need to improve this) - LLMozLib::getInstance()->focusBrowser( id, true ); - } - else - { - // send event to LLMozLib - LLMozLib::getInstance()->mouseMove( id, _x, _y ); - } - - } - - osg::ref_ptr _image; - int _x; - int _y; - int _buttonDelta; -}; - -void UBrowserManager::sendPointerEvent(UBrowserImage* image, int x, int y, int buttonMask) -{ - int deltaButton = (buttonMask&1) - (_previousButtonMask&1); - _previousButtonMask = buttonMask; - - _thread->add(new PointerEventOperation(image, x, y, deltaButton)); -} - - -struct KeyEventOperation : public osg::Operation -{ - KeyEventOperation(UBrowserImage* image, int key, bool isUnicode): - osg::Operation("key event",false), - _image(image), - _key(key), - _isUnicode(isUnicode) {} - - virtual void operator () (osg::Object* object) - { - int id = _image->getBrowserWindowId(); - if (_isUnicode) LLMozLib::getInstance()->unicodeInput( id, _key ); - else LLMozLib::getInstance()->keyPress( id, _key ); - } - - osg::ref_ptr _image; - int _key; - bool _isUnicode; -}; - -void UBrowserManager::sendKeyEvent(UBrowserImage* image, int key, bool keyDown) -{ - if (!keyDown) return; - - KeyMap::const_iterator itr = _keyMap.find(key); - if (_keyMap.find(key)==_keyMap.end()) _thread->add(new KeyEventOperation(image, key, true)); - else _thread->add(new KeyEventOperation(image, itr->second, false)); - -} - - -struct NavigateToOperation : public osg::Operation -{ - NavigateToOperation(UBrowserImage* image, const std::string& url): - osg::Operation("key event",false), - _image(image), - _url(url) {} - - virtual void operator () (osg::Object* object) - { - int id = _image->getBrowserWindowId(); - LLMozLib::getInstance()->navigateTo( id, _url ); - } - - osg::ref_ptr _image; - std::string _url; -}; - -void UBrowserManager::navigateTo(UBrowserImage* image, const std::string& url) -{ - _thread->add(new NavigateToOperation(image, url)); -} - -//////////////////////////////////////////////////////////////////////////////////// -// -// UBrowser implementation - -UBrowserImage::UBrowserImage(const std::string& homeURL, int width, int height): - _browserWindowId(0), - _needsUpdate(true) -{ - GLint internalFormat = GL_RGB; - GLenum pixelFormat = GL_BGR_EXT; - - setImage(width,height,1, internalFormat, pixelFormat, GL_UNSIGNED_BYTE, - 0, - osg::Image::NO_DELETE); - - setDataVariance(osg::Object::DYNAMIC); - setOrigin(osg::Image::TOP_LEFT); - - _homeURL = homeURL; - - UBrowserManager::instance()->registerUBrowserImage(this); - - -} - -UBrowserImage::~UBrowserImage() -{ - UBrowserManager::instance()->unregisterUBrowserImage(this); -} - -void UBrowserImage::sendPointerEvent(int x, int y, int buttonMask) -{ - UBrowserManager::instance()->sendPointerEvent(this, x, y, buttonMask); -} - -void UBrowserImage::sendKeyEvent(int key, bool keyDown) -{ - UBrowserManager::instance()->sendKeyEvent(this, key, keyDown); -} - -void UBrowserImage::navigateTo(const std::string& url) -{ - UBrowserManager::instance()->navigateTo(this, url); -} +#include "UBrowser.h" osg::Node* createInteractiveQuad(const osg::Vec3& origin, osg::Vec3& widthAxis, osg::Vec3& heightAxis, @@ -717,18 +50,20 @@ int main( int argc, char* argv[] ) { osg::ArgumentParser arguments(&argc, argv); - UBrowserManager::instance()->init(arguments[0]); + osgWidget::BrowserManager::instance()->init(arguments[0]); osgViewer::Viewer viewer(arguments); - typedef std::list< osg::ref_ptr > Images; + typedef std::list< osg::ref_ptr > Images; Images images; for(int i=1; i image = osgDB::readImageFile(url_browser); + if (image.valid()) images.push_back(image.get()); } }