From: Braden M. <br...@us...> - 2007-02-05 05:36:14
|
Update of /cvsroot/openvrml/openvrml/src/openvrml-xembed In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv12827/src/openvrml-xembed Added Files: .cvsignore Makefile.am bounded_buffer.h command_istream.cpp command_istream.h gtkvrmlbrowser.cpp gtkvrmlbrowser.h main.cpp plugin_streambuf.cpp plugin_streambuf.h Log Message: Changed the name of openvrml-gtkplug to openvrml-xembed. --- NEW FILE: .cvsignore --- Makefile Makefile.in openvrml-xembed --- NEW FILE: main.cpp --- // -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 78 -*- // // OpenVRML Mozilla plug-in // Copyright 2004, 2005, 2006 Braden N. McDaniel // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program 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 // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // # include <iostream> # include <sstream> # include <boost/lexical_cast.hpp> # include <boost/multi_index/detail/scope_guard.hpp> # include <boost/thread/thread.hpp> # include <unistd.h> // Must include before X11 headers. # include <boost/numeric/conversion/converter.hpp> # include <gtk/gtk.h> # include <openvrml/browser.h> # ifdef HAVE_CONFIG_H # include "config.h" # endif # include "gtkvrmlbrowser.h" # include "command_istream.h" # include "plugin_streambuf.h" using namespace openvrml_player; using namespace boost::multi_index::detail; // for scope_guard namespace { const char application_name[] = "OpenVRML XEmbed Control"; // // We don't already know what the URI of the initial stream is until we // start getting that data from the browser. This is a placeholder that // is used to identify the plugin_streambuf that will be used to receive // the initial stream data. // const char initial_stream_uri[] = "x-openvrml-initial:"; } namespace openvrml_player { struct command_istream_reader { command_istream_reader(command_istream & in, GtkVrmlBrowser & vrml_browser, GMainLoop & command_channel_loop): in_(&in), vrml_browser_(&vrml_browser), command_channel_loop_(&command_channel_loop) {} void operator()() const throw () { using std::string; string command_line; while (getline(*this->in_, command_line)) { using std::istringstream; istringstream command_line_stream(command_line); string command; command_line_stream >> command; if (command == "get-url-result") { using boost::shared_ptr; std::string url; int result; command_line_stream >> url >> result; shared_ptr<plugin_streambuf> streambuf = uninitialized_plugin_streambuf_map_.find(url); assert(streambuf); streambuf->set_get_url_result(result); } else if (command == "new-stream") { using boost::shared_ptr; size_t stream_id; std::string type, url; command_line_stream >> stream_id >> type >> url; shared_ptr<plugin_streambuf> streambuf = uninitialized_plugin_streambuf_map_.find(url); static bool got_initial_stream = false; if (!streambuf) { if (!got_initial_stream) { g_assert(uninitialized_plugin_streambuf_map_.size() == 1); streambuf = uninitialized_plugin_streambuf_map_.front(); got_initial_stream = true; } else { g_warning("Attempt to create an unrequested " "stream."); continue; } } streambuf->init(stream_id, url, type); } else if (command == "destroy-stream") { size_t stream_id; command_line_stream >> stream_id; plugin_streambuf_map_t::iterator pos = plugin_streambuf_map.find(stream_id); if (pos == plugin_streambuf_map.end()) { g_warning("Attempt to destroy a nonexistent stream."); continue; } pos->second->buf_.set_eof(); plugin_streambuf_map.erase(pos); } else if (command == "write") { size_t stream_id, length; command_line_stream >> stream_id >> length; plugin_streambuf_map_t::const_iterator pos = plugin_streambuf_map.find(stream_id); if (pos == plugin_streambuf_map.end()) { g_warning("Attempt to write to a nonexistent stream."); continue; } for (size_t i = 0; i < length; ++i) { pos->second->buf_.put(this->in_->get()); } } else if (command == "load-url") { string url; command_line_stream >> url; const gchar * urls[] = { g_strdup(url.c_str()), 0 }; scope_guard urls_guard = make_guard(g_free, const_cast<void *>( static_cast<const void *>(urls[0]))); boost::ignore_unused_variable_warning(urls_guard); gtk_vrml_browser_load_url(this->vrml_browser_, urls, 0); } } // // Got EOF from the command stream. Time to shut down. // // First, mark any outstanding uninitialized streams as failed so // that another thread doesn't block waiting for them. // while (!uninitialized_plugin_streambuf_map_.empty()) { uninitialized_plugin_streambuf_map_.front()->fail(); } // // Tell the command_channel_loop thread to quit. (This is our // "producer" thread; it's also the thread that spawned us.) // g_main_loop_quit(this->command_channel_loop_); } private: command_istream * const in_; GtkVrmlBrowser * const vrml_browser_; GMainLoop * const command_channel_loop_; }; } namespace { gboolean version, initial_stream; gchar ** args; GOptionEntry options[] = { { "version", 'v', 0, G_OPTION_ARG_NONE, &version, "Print the version information and exit", 0 }, { "initial-stream", 'i', 0, G_OPTION_ARG_NONE, &initial_stream, "Expect an initial stream", 0 }, { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &args, "the embedder's window ID", "XID" }, { 0, '\0', 0, G_OPTION_ARG_NONE, 0, 0, 0 } }; struct initial_stream_reader { initial_stream_reader( const boost::shared_ptr<plugin_streambuf> & streambuf, GtkVrmlBrowser & vrml_browser): streambuf_(streambuf), vrml_browser_(&vrml_browser) {} void operator()() const throw () { class plugin_istream : public openvrml::resource_istream { boost::shared_ptr<plugin_streambuf> streambuf_; public: explicit plugin_istream( const boost::shared_ptr<plugin_streambuf> & streambuf): openvrml::resource_istream(streambuf.get()), streambuf_(streambuf) {} virtual ~plugin_istream() throw () {} private: virtual const std::string do_url() const throw (std::bad_alloc) { return this->streambuf_->url(); } virtual const std::string do_type() const throw (std::bad_alloc) { return this->streambuf_->type(); } virtual bool do_data_available() const throw () { return this->streambuf_->data_available(); } } in(this->streambuf_); gtk_vrml_browser_set_world(this->vrml_browser_, in); } private: boost::shared_ptr<plugin_streambuf> streambuf_; GtkVrmlBrowser * vrml_browser_; }; struct command_channel_loop { command_channel_loop(GIOChannel & command_channel, command_istream & command_in, GtkVrmlBrowser & vrml_browser): command_channel_(&command_channel), command_in_(&command_in), vrml_browser_(&vrml_browser) {} void operator()() const throw () { using boost::function0; using boost::scoped_ptr; using boost::thread; GMainContext * const main_context = g_main_context_new(); scope_guard main_context_guard = make_guard(g_main_context_unref, main_context); boost::ignore_unused_variable_warning(main_context_guard); GMainLoop * const main_loop = g_main_loop_new(main_context, false); scope_guard main_loop_guard = make_guard(g_main_loop_unref, main_loop); boost::ignore_unused_variable_warning(main_loop_guard); GSource * const command_watch = g_io_create_watch(this->command_channel_, GIOCondition(G_IO_IN | G_IO_HUP)); scope_guard command_watch_guard = make_guard(g_source_unref, command_watch); boost::ignore_unused_variable_warning(command_watch_guard); static const GDestroyNotify notify = 0; g_source_set_callback( command_watch, reinterpret_cast<GSourceFunc>(::command_data_available), static_cast<command_streambuf *>(this->command_in_->rdbuf()), notify); const guint command_watch_id = g_source_attach(command_watch, main_context); g_assert(command_watch_id != 0); // // The command_istream_reader thread is our "consumer" thread. // function0<void> read_commands = command_istream_reader(*this->command_in_, *this->vrml_browser_, *main_loop); const scoped_ptr<thread> command_reader_thread(new thread(read_commands)); g_main_loop_run(main_loop); // // If we're here, our consumer thread is done. Join it and tell // the GTK+ main loop to quit. // command_reader_thread->join(); gtk_main_quit(); } private: GIOChannel * const command_channel_; command_istream * const command_in_; GtkVrmlBrowser * const vrml_browser_; }; G_GNUC_INTERNAL void command_channel_shutdown(GIOChannel * command_channel); G_GNUC_INTERNAL void request_channel_shutdown(GIOChannel * request_channel); } int main(int argc, char * argv[]) { using std::cout; using std::cerr; using std::endl; using std::vector; using boost::function0; using boost::ref; using boost::shared_ptr; using boost::thread; using boost::thread_group; using namespace openvrml_player; g_thread_init(0); gdk_threads_init(); g_set_application_name(application_name); gtk_init(&argc, &argv); gtk_gl_init(&argc, &argv); GError * error = 0; scope_guard error_guard = make_guard(g_error_free, ref(error)); GOptionContext * const context = g_option_context_new("- render VRML worlds"); const gchar * const translation_domain = 0; g_option_context_add_main_entries(context, options, translation_domain); g_option_context_add_group(context, gtk_get_option_group(true)); gboolean succeeded = g_option_context_parse(context, &argc, &argv, &error); if (!succeeded) { if (error) { g_critical(error->message); } return EXIT_FAILURE; } if (version) { cout << application_name << ' ' << PACKAGE_VERSION << endl; return EXIT_SUCCESS; } if (!::args) { cerr << argv[0] << ": missing required XID argument" << endl; return EXIT_FAILURE; } GdkNativeWindow socket_id; try { socket_id = boost::lexical_cast<GdkNativeWindow>(::args[0]); } catch (const boost::bad_lexical_cast & ex) { cerr << argv[0] << ": expected integer value for XID argument" << endl; return EXIT_FAILURE; } GIOChannel * const request_channel = g_io_channel_unix_new(1); // stdout g_return_val_if_fail(request_channel, EXIT_FAILURE); scope_guard request_channel_guard = make_guard(request_channel_shutdown, request_channel); boost::ignore_unused_variable_warning(request_channel_guard); GIOStatus status = g_io_channel_set_encoding(request_channel, 0, // binary (no encoding) &error); if (status != G_IO_STATUS_NORMAL) { if (error) { g_critical(error->message); } return EXIT_FAILURE; } GtkWidget * const window = gtk_plug_new(socket_id); g_return_val_if_fail(window, EXIT_FAILURE); GtkWidget * const vrml_browser = gtk_vrml_browser_new(request_channel); g_return_val_if_fail(vrml_browser, EXIT_FAILURE); gtk_container_add(GTK_CONTAINER(window), vrml_browser); gtk_widget_show_all(window); thread_group threads; GIOChannel * const command_channel = g_io_channel_unix_new(0); // stdin g_return_val_if_fail(command_channel, EXIT_FAILURE); scope_guard command_channel_guard = make_guard(command_channel_shutdown, command_channel); boost::ignore_unused_variable_warning(command_channel_guard); error = 0; status = g_io_channel_set_encoding(command_channel, 0, // binary (no encoding) &error); if (status != G_IO_STATUS_NORMAL) { if (error) { g_critical(error->message); } return EXIT_FAILURE; } command_istream command_in; function0<void> command_channel_loop_func = command_channel_loop(*command_channel, command_in, *GTK_VRML_BROWSER(vrml_browser)); threads.create_thread(command_channel_loop_func); if (::initial_stream) { const shared_ptr<plugin_streambuf> initial_stream( new plugin_streambuf(::initial_stream_uri)); uninitialized_plugin_streambuf_map_.insert(::initial_stream_uri, initial_stream); const function0<void> initial_stream_reader_func = initial_stream_reader(initial_stream, *GTK_VRML_BROWSER(vrml_browser)); threads.create_thread(initial_stream_reader_func); } gtk_main(); threads.join_all(); error_guard.dismiss(); } namespace { void command_channel_shutdown(GIOChannel * const command_channel) { using boost::ref; static const gboolean flush = true; GError * error = 0; scope_guard error_guard = make_guard(g_error_free, ref(error)); const GIOStatus status = g_io_channel_shutdown(command_channel, flush, &error); if (status != G_IO_STATUS_NORMAL) { if (error) { g_critical(error->message); } } g_io_channel_unref(command_channel); error_guard.dismiss(); } void request_channel_shutdown(GIOChannel * const request_channel) { using boost::ref; static const gboolean flush = false; GError * error = 0; scope_guard error_guard = make_guard(g_error_free, ref(error)); GIOStatus status = g_io_channel_shutdown(request_channel, flush, &error); if (status != G_IO_STATUS_NORMAL) { if (error) { g_critical(error->message); } } g_io_channel_unref(request_channel); error_guard.dismiss(); } } --- NEW FILE: gtkvrmlbrowser.cpp --- // -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; -*- // // OpenVRML Mozilla plug-in // Copyright 2004, 2005, 2006 Braden N. McDaniel // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program 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 // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // # include <iostream> # include <sstream> # include <boost/multi_index/detail/scope_guard.hpp> // Must include before X11 headers. # include <boost/numeric/conversion/converter.hpp> # include <X11/keysym.h> # include <gdk/gdkx.h> # include <openvrml/browser.h> # include <openvrml/gl/viewer.h> # include "gtkvrmlbrowser.h" # include "plugin_streambuf.h" using namespace boost::multi_index::detail; // for scope_guard extern "C" { void gtk_vrml_browser_class_init(GtkVrmlBrowserClass * klass); void gtk_vrml_browser_init(GtkVrmlBrowser * vrml_browser); G_GNUC_INTERNAL gboolean gtk_vrml_browser_destroy(GtkWidget * widget, GdkEvent * event, gpointer data); G_GNUC_INTERNAL gboolean gtk_vrml_browser_realize(GtkWidget * widget, GdkEvent * event, gpointer data); G_GNUC_INTERNAL gboolean gtk_vrml_browser_expose_event(GtkWidget * widget, GdkEventExpose * event, gpointer data); G_GNUC_INTERNAL gboolean gtk_vrml_browser_configure_event(GtkWidget * widget, GdkEventConfigure * event, gpointer data); G_GNUC_INTERNAL gboolean gtk_vrml_browser_key_press_event(GtkWidget * widget, GdkEventKey * event, gpointer data); G_GNUC_INTERNAL gboolean gtk_vrml_browser_button_press_event(GtkWidget * widget, GdkEventButton * event, gpointer data); G_GNUC_INTERNAL gboolean gtk_vrml_browser_button_release_event(GtkWidget * widget, GdkEventButton * event, gpointer data); G_GNUC_INTERNAL gboolean gtk_vrml_browser_motion_notify_event(GtkWidget * widget, GdkEventMotion * event, gpointer data); G_GNUC_INTERNAL gint gtk_vrml_browser_timeout_callback(gpointer ptr); } GType gtk_vrml_browser_get_type() { static GType type = 0; if (!type) { static const GTypeInfo info = { sizeof (GtkVrmlBrowserClass), 0, // base_init 0, // base_finalize reinterpret_cast<GClassInitFunc>(gtk_vrml_browser_class_init), 0, // class_finalize 0, // class_data sizeof (GtkVrmlBrowser), 0, // n_preallocs reinterpret_cast<GInstanceInitFunc>(gtk_vrml_browser_init), 0 // value_table }; type = g_type_register_static(GTK_TYPE_DRAWING_AREA, "GtkVrmlBrowser", &info, GTypeFlags(0)); } return type; } namespace { G_GNUC_INTERNAL GdkGLConfig * gl_config; class G_GNUC_INTERNAL resource_fetcher : public openvrml::resource_fetcher { GIOChannel * request_channel_; public: explicit resource_fetcher(GIOChannel & request_channel); private: virtual std::auto_ptr<openvrml::resource_istream> do_get_resource(const std::string & uri); }; class GtkGLViewer; class G_GNUC_INTERNAL browser_listener : public openvrml::browser_listener { GtkGLViewer & viewer_; public: explicit browser_listener(GtkGLViewer & viewer); private: virtual void do_browser_changed(const openvrml::browser_event & event); }; class G_GNUC_INTERNAL GtkGLViewer : public openvrml::gl::viewer { friend class browser_listener; friend void (::gtk_vrml_browser_load_url)(GtkVrmlBrowser * vrml_browser, const gchar ** url, const gchar ** parameter); friend void (::gtk_vrml_browser_set_world)(GtkVrmlBrowser * vrml_browser, openvrml::resource_istream & in); friend gint (::gtk_vrml_browser_timeout_callback)(gpointer ptr); friend gboolean (::gtk_vrml_browser_expose_event)(GtkWidget *, GdkEventExpose *, gpointer); friend gboolean (::gtk_vrml_browser_motion_notify_event)(GtkWidget *, GdkEventMotion *, gpointer); ::resource_fetcher fetcher_; openvrml::browser browser_; ::browser_listener browser_listener_; bool browser_initialized_; boost::mutex browser_initialized_mutex_; GtkVrmlBrowser & vrml_browser_; guint timer; public: bool redrawNeeded; GtkGLViewer(GIOChannel & request_channel, GtkVrmlBrowser & vrml_browser); virtual ~GtkGLViewer() throw (); void timer_update(); protected: // // Implement pure virtual methods from openvrml::gl::viewer. // virtual void post_redraw(); virtual void set_cursor(openvrml::gl::viewer::cursor_style); virtual void swap_buffers(); virtual void set_timer(double); }; } GtkWidget * gtk_vrml_browser_new(GIOChannel * const request_channel) { GtkVrmlBrowser * const vrml_browser = GTK_VRML_BROWSER(g_object_new(GTK_TYPE_VRML_BROWSER, 0)); try { vrml_browser->viewer = new GtkGLViewer(*request_channel, *vrml_browser); } catch (std::bad_alloc &) { g_return_val_if_reached(0); } static_cast<GtkGLViewer *>(vrml_browser->viewer) ->resize(GTK_WIDGET(vrml_browser)->allocation.width, GTK_WIDGET(vrml_browser)->allocation.height); return GTK_WIDGET(vrml_browser); } void gtk_vrml_browser_load_url(GtkVrmlBrowser * const vrml_browser, const gchar ** url, const gchar ** parameter) { using std::string; using std::vector; GtkGLViewer & viewer = *static_cast<GtkGLViewer *>(vrml_browser->viewer); vector<string> url_vec, param_vec; while (url && *url) { url_vec.push_back(*(url++)); } while (parameter && *parameter) { param_vec.push_back(*(parameter++)); } { boost::mutex::scoped_lock lock(viewer.browser_initialized_mutex_); viewer.browser_initialized_ = false; } viewer.browser_.load_url(url_vec, param_vec); } void gtk_vrml_browser_set_world(GtkVrmlBrowser * vrml_browser, openvrml::resource_istream & in) { GtkGLViewer & viewer = *static_cast<GtkGLViewer *>(vrml_browser->viewer); { boost::mutex::scoped_lock lock(viewer.browser_initialized_mutex_); viewer.browser_initialized_ = false; } viewer.browser_.set_world(in); } void gtk_vrml_browser_class_init(GtkVrmlBrowserClass *) {} void gtk_vrml_browser_init(GtkVrmlBrowser * const vrml_browser) { vrml_browser->viewer = 0; if (!::gl_config) { static const int attrib_list[] = { // GDK_GL_ALPHA_SIZE, 1, GDK_GL_DOUBLEBUFFER, GDK_GL_DEPTH_SIZE, 1, GDK_GL_RGBA, GDK_GL_RED_SIZE, 1, GDK_GL_ATTRIB_LIST_NONE }; ::gl_config = gdk_gl_config_new(attrib_list); } static GdkGLContext * const share_list = 0; static const gboolean direct = false; static const int render_type = GDK_GL_RGBA_TYPE; gtk_widget_set_gl_capability(GTK_WIDGET(vrml_browser), ::gl_config, share_list, direct, render_type); gtk_widget_add_events(GTK_WIDGET(vrml_browser), GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_FOCUS_CHANGE_MASK); g_object_set(G_OBJECT(vrml_browser), "can-focus", true, NULL); g_object_connect( G_OBJECT(vrml_browser), "signal::destroy_event", G_CALLBACK(gtk_vrml_browser_destroy), 0, "signal::expose_event", G_CALLBACK(gtk_vrml_browser_expose_event), 0, "signal::configure_event", G_CALLBACK(gtk_vrml_browser_configure_event), 0, "signal::key_press_event", G_CALLBACK(gtk_vrml_browser_key_press_event), 0, "signal::button_press_event", G_CALLBACK(gtk_vrml_browser_button_press_event), 0, "signal::button_release_event", G_CALLBACK(gtk_vrml_browser_button_release_event), 0, "signal::motion_notify_event", G_CALLBACK(gtk_vrml_browser_motion_notify_event), 0, NULL); } gboolean gtk_vrml_browser_destroy(GtkWidget * const widget, GdkEvent *, gpointer) { delete static_cast<GtkGLViewer *>(GTK_VRML_BROWSER(widget)->viewer); return true; } gboolean gtk_vrml_browser_realize(GtkWidget *, GdkEvent *, gpointer) { return true; } gboolean gtk_vrml_browser_expose_event(GtkWidget * const widget, GdkEventExpose * const event, gpointer) { GdkGLDrawable * const gl_drawable = gtk_widget_get_gl_drawable(widget); g_assert(gl_drawable); GdkGLContext * const gl_context = gtk_widget_get_gl_context(widget); g_assert(gl_context); GtkGLViewer & viewer = *static_cast<GtkGLViewer *>(GTK_VRML_BROWSER(widget)->viewer); boost::mutex::scoped_lock lock(viewer.browser_initialized_mutex_); if (!viewer.browser_initialized_) { return true; } if (event->count == 0 && gdk_gl_drawable_make_current(gl_drawable, gl_context)) { viewer.redraw(); } viewer.redrawNeeded = false; if (viewer.timer == 0) { viewer.timer_update(); } return true; } gboolean gtk_vrml_browser_configure_event(GtkWidget * const widget, GdkEventConfigure *, gpointer) { GdkGLDrawable * const gl_drawable = gtk_widget_get_gl_drawable(widget); g_assert(gl_drawable); GdkGLContext * const gl_context = gtk_widget_get_gl_context(widget); g_assert(gl_context); if (GTK_VRML_BROWSER(widget)->viewer && gdk_gl_drawable_make_current(gl_drawable, gl_context)) { GtkGLViewer & viewer = *static_cast<GtkGLViewer *>(GTK_VRML_BROWSER(widget)->viewer); viewer.resize(widget->allocation.width, widget->allocation.height); } return true; } gboolean gtk_vrml_browser_key_press_event(GtkWidget * const widget, GdkEventKey * const event, gpointer) { using openvrml::gl::viewer; viewer::event_info info; info.event = viewer::event_key_down; switch (event->keyval) { case XK_Home: info.what = viewer::key_home; break; case XK_Left: info.what = viewer::key_left; break; case XK_Up: info.what = viewer::key_up; break; case XK_Right: info.what = viewer::key_right; break; case XK_Down: info.what = viewer::key_down; break; case XK_Page_Up: info.what = viewer::key_page_up; break; case XK_Page_Down: info.what = viewer::key_page_down; break; default: if (event->length <= 0) { return true; } info.what = event->string[0]; } GdkGLDrawable * const gl_drawable = gtk_widget_get_gl_drawable(widget); g_assert(gl_drawable); GdkGLContext * const gl_context = gtk_widget_get_gl_context(widget); g_assert(gl_context); if (gdk_gl_drawable_make_current(gl_drawable, gl_context)) { GtkGLViewer * const viewer = static_cast<GtkGLViewer *>(GTK_VRML_BROWSER(widget)->viewer); g_assert(viewer); viewer->input(&info); } return true; } gboolean gtk_vrml_browser_button_press_event(GtkWidget * const widget, GdkEventButton * const event, gpointer) { using openvrml::gl::viewer; gtk_widget_grab_focus(widget); viewer::event_info info; info.event = viewer::event_mouse_click; switch (event->button) { case Button1: info.what = 0; break; case Button2: info.what = 1; break; case Button3: info.what = 2; break; } info.x = int(event->x); info.y = int(event->y); GdkGLDrawable * const gl_drawable = gtk_widget_get_gl_drawable(widget); g_assert(gl_drawable); GdkGLContext * const gl_context = gtk_widget_get_gl_context(widget); g_assert(gl_context); if (gdk_gl_drawable_make_current(gl_drawable, gl_context)) { GtkGLViewer * const viewer = static_cast<GtkGLViewer *>(GTK_VRML_BROWSER(widget)->viewer); g_assert(viewer); viewer->input(&info); } return true; } gboolean gtk_vrml_browser_button_release_event(GtkWidget * const widget, GdkEventButton * const event, gpointer) { using openvrml::gl::viewer; viewer::event_info info; info.event = viewer::event_mouse_release; switch (event->button) { case Button1: info.what = 0; break; case Button2: info.what = 1; break; case Button3: info.what = 2; break; } info.x = int(event->x); info.y = int(event->y); GdkGLDrawable * const gl_drawable = gtk_widget_get_gl_drawable(widget); g_assert(gl_drawable); GdkGLContext * const gl_context = gtk_widget_get_gl_context(widget); g_assert(gl_context); if (gdk_gl_drawable_make_current(gl_drawable, gl_context)) { GtkGLViewer * const viewer = static_cast<GtkGLViewer *>(GTK_VRML_BROWSER(widget)->viewer); g_assert(viewer); viewer->input(&info); } return true; } gboolean gtk_vrml_browser_motion_notify_event(GtkWidget * const widget, GdkEventMotion * const event, gpointer) { using openvrml::gl::viewer; viewer::event_info info; info.event = viewer::event_mouse_drag; info.what = 0; if (event->state & Button1Mask) { info.what = 0; } else if (event->state & Button2Mask) { info.what = 1; } else if (event->state & Button3Mask) { info.what = 2; } else { info.event = viewer::event_mouse_move; } info.x = int(event->x); info.y = int(event->y); GdkGLDrawable * const gl_drawable = gtk_widget_get_gl_drawable(widget); g_assert(gl_drawable); GdkGLContext * const gl_context = gtk_widget_get_gl_context(widget); g_assert(gl_context); if (gdk_gl_drawable_make_current(gl_drawable, gl_context)) { g_assert(GTK_VRML_BROWSER(widget)->viewer); GtkGLViewer & viewer = *static_cast<GtkGLViewer *>(GTK_VRML_BROWSER(widget)->viewer); boost::mutex::scoped_lock lock(viewer.browser_initialized_mutex_); if (!viewer.browser_initialized_) { return true; } viewer.input(&info); } return true; } gint gtk_vrml_browser_timeout_callback(const gpointer ptr) { assert(ptr); GtkGLViewer & viewer = *static_cast<GtkGLViewer *>(ptr); viewer.timer_update(); return false; } namespace { resource_fetcher::resource_fetcher(GIOChannel & request_channel): request_channel_(&request_channel) {} std::auto_ptr<openvrml::resource_istream> resource_fetcher::do_get_resource(const std::string & uri) { using openvrml_player::plugin_streambuf; class plugin_resource_istream : public openvrml::resource_istream { const boost::shared_ptr<plugin_streambuf> streambuf_; GIOChannel * const request_channel_; public: plugin_resource_istream(const std::string & uri, GIOChannel * const request_channel): openvrml::resource_istream(0), streambuf_(new plugin_streambuf(uri)), request_channel_(request_channel) { using std::ostringstream; using boost::ref; using openvrml_player::uninitialized_plugin_streambuf_map_; this->rdbuf(this->streambuf_.get()); uninitialized_plugin_streambuf_map_.insert(uri, this->streambuf_); ostringstream request; request << "get-url " << uri << '\n'; gsize bytes_written; GError * error = 0; scope_guard error_guard = make_guard(g_error_free, ref(error)); boost::ignore_unused_variable_warning(error_guard); GIOStatus io_status = g_io_channel_write_chars(this->request_channel_, request.str().data(), request.str().length(), &bytes_written, &error); if (io_status != G_IO_STATUS_NORMAL) { g_warning(error->message); this->setstate(ios_base::badbit); return; } io_status = g_io_channel_flush(this->request_channel_, &error); if (io_status != G_IO_STATUS_NORMAL) { g_warning(error->message); this->setstate(ios_base::badbit); return; } // // This blocks until we receive a get-url-result command. // const int get_url_result = this->streambuf_->get_url_result(); if (get_url_result != 0) { this->setstate(ios_base::badbit); } error_guard.dismiss(); } private: virtual const std::string do_url() const throw () { return this->streambuf_->url(); } virtual const std::string do_type() const throw () { return this->streambuf_->type(); } virtual bool do_data_available() const throw () { return this->streambuf_->data_available(); } }; return std::auto_ptr<openvrml::resource_istream>( new plugin_resource_istream(uri, this->request_channel_)); } browser_listener::browser_listener(GtkGLViewer & viewer): viewer_(viewer) {} void browser_listener::do_browser_changed(const openvrml::browser_event & event) { if (event.id() == openvrml::browser_event::initialized) { using boost::mutex; mutex::scoped_lock lock(this->viewer_.browser_initialized_mutex_); this->viewer_.browser_initialized_ = true; gdk_threads_enter(); this->viewer_.post_redraw(); gdk_threads_leave(); } } // // We use stdout for communication with the host process; so send // all browser output to stderr. // GtkGLViewer::GtkGLViewer(GIOChannel & request_channel, GtkVrmlBrowser & vrml_browser): fetcher_(request_channel), browser_(this->fetcher_, std::cerr, std::cerr), browser_listener_(*this), browser_initialized_(true), vrml_browser_(vrml_browser), timer(0), redrawNeeded(false) { this->browser_.add_listener(this->browser_listener_); this->browser_.viewer(this); } GtkGLViewer::~GtkGLViewer() throw () { if (this->timer) { g_source_remove(timer); } this->browser_.remove_listener(this->browser_listener_); } void GtkGLViewer::post_redraw() { if (!this->redrawNeeded) { this->redrawNeeded = true; gtk_widget_queue_draw(GTK_WIDGET(&this->vrml_browser_)); } } void GtkGLViewer::set_cursor(cursor_style style) { GdkCursor * cursor(0); switch(style) { case cursor_inherit: XDefineCursor(GDK_WINDOW_XDISPLAY( GTK_WIDGET(&this->vrml_browser_)->window), GDK_WINDOW_XWINDOW( GTK_WIDGET(&this->vrml_browser_)->window), None); return; case cursor_info: cursor = gdk_cursor_new(GDK_HAND1); break; case cursor_cycle: cursor = gdk_cursor_new(GDK_EXCHANGE); break; case cursor_up_down: cursor = gdk_cursor_new(GDK_SB_V_DOUBLE_ARROW); break; case cursor_crosshair: cursor = gdk_cursor_new(GDK_CROSSHAIR); break; default: cursor = gdk_cursor_new(GDK_ARROW); } gdk_window_set_cursor(GTK_WIDGET(&this->vrml_browser_)->window, cursor); gdk_cursor_destroy(cursor); } void GtkGLViewer::swap_buffers() { GdkGLDrawable * const gl_drawable = gtk_widget_get_gl_drawable(GTK_WIDGET(&this->vrml_browser_)); gdk_gl_drawable_swap_buffers(gl_drawable); } void GtkGLViewer::set_timer(const double t) { if (!this->timer) { this->timer = g_timeout_add(guint(10.0 * (t + 1)), GtkFunction(gtk_vrml_browser_timeout_callback), this); } } void GtkGLViewer::timer_update() { this->timer = 0; this->viewer::update(); } } --- NEW FILE: plugin_streambuf.h --- // -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; -*- // // OpenVRML Mozilla plug-in // Copyright 2004, 2005, 2006 Braden N. McDaniel // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program 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 // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // # ifndef OPENVRML_PLAYER_PLUGIN_STREAMBUF_H # define OPENVRML_PLAYER_PLUGIN_STREAMBUF_H # include <map> # include <set> # include <streambuf> # include <boost/shared_ptr.hpp> # include <boost/enable_shared_from_this.hpp> # include "bounded_buffer.h" namespace openvrml_player { class command_istream_reader; class plugin_streambuf : public boost::enable_shared_from_this<plugin_streambuf>, public std::streambuf { friend class command_istream_reader; mutable boost::mutex mutex_; int get_url_result_; mutable boost::condition received_get_url_result_; bool initialized_; mutable boost::condition streambuf_initialized_or_failed_; std::string url_; std::string type_; bounded_buffer<char_type, 16384> buf_; int_type i_; char_type c_; protected: virtual int_type underflow(); public: explicit plugin_streambuf(const std::string & requested_url); void set_get_url_result(int result); int get_url_result() const; void init(size_t stream_id, const std::string & received_url, const std::string & type); void fail(); const std::string & url() const; const std::string & type() const; bool data_available() const; }; extern class uninitialized_plugin_streambuf_map { mutable boost::mutex mutex_; typedef std::multimap<std::string, boost::shared_ptr<plugin_streambuf> > map_t; map_t map_; public: const boost::shared_ptr<plugin_streambuf> find(const std::string & url) const; void insert(const std::string & url, const boost::shared_ptr<plugin_streambuf> & streambuf); bool erase(const std::string & url); size_t size() const; bool empty() const; const boost::shared_ptr<plugin_streambuf> front() const; } uninitialized_plugin_streambuf_map_; typedef std::map<size_t, boost::shared_ptr<plugin_streambuf> > plugin_streambuf_map_t; extern plugin_streambuf_map_t plugin_streambuf_map; } # endif // ifndef OPENVRML_PLAYER_PLUGIN_STREAMBUF_H --- NEW FILE: command_istream.h --- // -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; -*- // // OpenVRML Mozilla plug-in // Copyright 2004, 2005, 2006 Braden N. McDaniel // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program 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 // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // # ifndef OPENVRML_PLAYER_COMMAND_ISTREAM_H # define OPENVRML_PLAYER_COMMAND_ISTREAM_H # include <streambuf> # include <glib.h> # include "bounded_buffer.h" extern "C" gboolean command_data_available(GIOChannel * source, GIOCondition condition, gpointer data); namespace openvrml_player { class command_streambuf : boost::noncopyable, public std::streambuf { friend gboolean (::command_data_available)(GIOChannel * source, GIOCondition condition, gpointer data); bounded_buffer<char_type, 16384> source_buffer_; char_type c_; protected: virtual int_type underflow(); public: command_streambuf(); }; class command_istream : boost::noncopyable, public std::istream { command_streambuf buf_; public: command_istream(); }; } # endif // ifndef OPENVRML_PLAYER_COMMAND_ISTREAM_H --- NEW FILE: gtkvrmlbrowser.h --- /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; -*- * * OpenVRML Mozilla plug-in * Copyright 2004, 2005, 2006 Braden N. McDaniel * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ # ifndef GTK_VRML_BROWSER_H # define GTK_VRML_BROWSER_H # include <gtk/gtkdrawingarea.h> # include <gtk/gtkgl.h> G_BEGIN_DECLS # define GTK_TYPE_VRML_BROWSER (gtk_vrml_browser_get_type ()) # define GTK_VRML_BROWSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_VRML_BROWSER, GtkVrmlBrowser)) # define GTK_VRML_BROWSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_VRML_BROWSER, GtkVrmlBrowserClass)) # define GTK_IS_VRML_BROWSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_VRML_BROWSER)) # define GTK_IS_VRML_BROWSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_VRML_BROWSER)) # define GTK_VRML_BROWSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_VRML_BROWSER, GtkVrmlBrowserClass)) typedef struct GtkVrmlBrowser_ GtkVrmlBrowser; typedef struct GtkVrmlBrowserClass_ GtkVrmlBrowserClass; struct GtkVrmlBrowser_ { GtkDrawingArea drawing_area; void *viewer; }; struct GtkVrmlBrowserClass_ { GtkDrawingAreaClass parent_class; }; GType gtk_vrml_browser_get_type(void) G_GNUC_CONST; GtkWidget *gtk_vrml_browser_new(GIOChannel *request_channel); void gtk_vrml_browser_load_url(GtkVrmlBrowser *vrml_browser, const gchar **url, const gchar **parameter); G_END_DECLS # ifdef __cplusplus namespace openvrml { class resource_istream; } // // Since OpenVRML has a C++ interface, exposing this to C is Hard. // void gtk_vrml_browser_set_world(GtkVrmlBrowser * vrml_browser, openvrml::resource_istream & in); # endif # endif /* ifndef GTK_VRML_BROWSER_H */ --- NEW FILE: Makefile.am --- AM_CPPFLAGS = \ -I$(top_srcdir)/lib/gtkglext \ -I$(top_builddir)/lib/gtkglext \ -I$(top_builddir)/lib/gtkglext/gdk \ -I$(top_builddir)/src/libopenvrml \ -I$(top_srcdir)/src/libopenvrml \ -I$(top_builddir)/src/libopenvrml-gl \ -I$(top_srcdir)/src/libopenvrml-gl \ -I$(mozincludedir) \ -DGTK_DISABLE_DEPRECATED AM_CXXFLAGS = @PTHREAD_CFLAGS@ @GTK_CFLAGS@ @GL_CFLAGS@ AM_LDFLAGS = \ @OPENVRML_RPATH@ \ @JNI_LIBS@ \ @GTK_LIBS@ \ @GL_LIBS@ \ -lXmu -lXt @X_PRE_LIBS@ @X_LIBS@ @X_EXTRA_LIBS@ \ -lboost_thread \ @PTHREAD_LIBS@ LDADD = $(top_builddir)/src/libopenvrml-gl/libopenvrml-gl.la \ $(top_builddir)/src/libopenvrml/libopenvrml.la \ $(top_builddir)/lib/gtkglext/gtk/libgtkglext-x11-1.0.la \ $(top_builddir)/lib/gtkglext/gdk/libgdkglext-x11-1.0.la if ENABLE_XEMBED libexec_PROGRAMS = openvrml-xembed endif noinst_HEADERS = \ bounded_buffer.h \ command_istream.h \ plugin_streambuf.h \ gtkvrmlbrowser.h openvrml_xembed_SOURCES = \ main.cpp \ command_istream.cpp \ plugin_streambuf.cpp \ gtkvrmlbrowser.cpp EXTRA_DIST = $(openvrml_xembed_SOURCES) --- NEW FILE: command_istream.cpp --- // -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; -*- // // OpenVRML Mozilla plug-in // Copyright 2004, 2005, 2006 Braden N. McDaniel // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program 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 // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // # include <cassert> # include <cerrno> # include "command_istream.h" openvrml_player::command_streambuf::command_streambuf(): c_('\0') { this->setg(&this->c_, &this->c_, &this->c_); } openvrml_player::command_streambuf::int_type openvrml_player::command_streambuf::underflow() { const int_type i = this->source_buffer_.get(); if (traits_type::eq_int_type(i, traits_type::eof())) { return traits_type::eof(); } this->c_ = traits_type::to_char_type(i); this->setg(&this->c_, &this->c_, &this->c_ + 1); return i; } openvrml_player::command_istream::command_istream(): std::istream(&this->buf_) {} gboolean command_data_available(GIOChannel * source, GIOCondition, gpointer data) { using namespace openvrml_player; typedef command_istream::traits_type traits_type; command_streambuf & streambuf = *static_cast<command_streambuf *>(data); do { gchar c; gsize bytes_read; GError * error = 0; const GIOStatus status = g_io_channel_read_chars(source, &c, 1, &bytes_read, &error); if (status == G_IO_STATUS_ERROR) { if (error) { g_warning(error->message); g_error_free(error); } return false; } if (status == G_IO_STATUS_EOF) { streambuf.source_buffer_.set_eof(); return false; } if (status == G_IO_STATUS_AGAIN) { continue; } g_return_val_if_fail(status == G_IO_STATUS_NORMAL, false); g_assert(bytes_read == 1); streambuf.source_buffer_.put(c); } while (g_io_channel_get_buffer_condition(source) & G_IO_IN); return true; } --- NEW FILE: plugin_streambuf.cpp --- // -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 78 -*- // // OpenVRML Mozilla plug-in // Copyright 2004, 2005, 2006 Braden N. McDaniel // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program 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 // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // # include <glib.h> # include "plugin_streambuf.h" openvrml_player::plugin_streambuf:: plugin_streambuf(const std::string & requested_url): get_url_result_(-1), initialized_(false), url_(requested_url), i_(0), c_('\0') { // // This is really just here to emphasize that c_ must not be EOF. // this->i_ = traits_type::not_eof(this->i_); this->c_ = traits_type::to_char_type( traits_type::not_eof(traits_type::to_int_type(this->c_))); this->setg(&this->c_, &this->c_, &this->c_); } void openvrml_player::plugin_streambuf::set_get_url_result(const int result) { boost::mutex::scoped_lock lock(this->mutex_); assert(this->get_url_result_ == -1); this->get_url_result_ = result; this->received_get_url_result_.notify_all(); } int openvrml_player::plugin_streambuf::get_url_result() const { boost::mutex::scoped_lock lock(this->mutex_); while (this->get_url_result_ == -1) { this->received_get_url_result_.wait(lock); } return this->get_url_result_; } void openvrml_player::plugin_streambuf::init(const size_t stream_id, const std::string & received_url, const std::string & type) { g_assert(stream_id); g_assert(!received_url.empty()); g_assert(!type.empty()); boost::mutex::scoped_lock lock(this->mutex_); bool succeeded = uninitialized_plugin_streambuf_map_.erase(this->url_); g_assert(succeeded); this->url_ = received_url; this->type_ = type; this->initialized_ = true; const boost::shared_ptr<plugin_streambuf> this_ = shared_from_this(); succeeded = plugin_streambuf_map.insert(make_pair(stream_id, this_)) .second; g_assert(succeeded); this->streambuf_initialized_or_failed_.notify_all(); } void openvrml_player::plugin_streambuf::fail() { boost::mutex::scoped_lock lock(this->mutex_); const bool succeeded = uninitialized_plugin_streambuf_map_.erase(this->url_); g_assert(succeeded); this->buf_.set_eof(); this->streambuf_initialized_or_failed_.notify_all(); } const std::string & openvrml_player::plugin_streambuf::url() const { boost::mutex::scoped_lock lock(this->mutex_); while (!this->initialized_) { this->streambuf_initialized_or_failed_.wait(lock); } return this->url_; } const std::string & openvrml_player::plugin_streambuf::type() const { boost::mutex::scoped_lock lock(this->mutex_); while (!this->initialized_) { this->streambuf_initialized_or_failed_.wait(lock); } return this->type_; } bool openvrml_player::plugin_streambuf::data_available() const { // // It may seem a bit counterintuitive to return true here if the stream // has been destroyed; however, if we don't return true in this case, // clients may never get EOF from the stream. // return this->buf_.buffered() > 0 || this->buf_.eof(); } openvrml_player::plugin_streambuf::int_type openvrml_player::plugin_streambuf::underflow() { boost::mutex::scoped_lock lock(this->mutex_); while (!this->initialized_) { this->streambuf_initialized_or_failed_.wait(lock); } if (traits_type::eq_int_type(this->i_, traits_type::eof())) { return traits_type::eof(); } this->i_ = this->buf_.get(); this->c_ = traits_type::to_char_type(this->i_); if (traits_type::eq_int_type(this->i_, traits_type::eof())) { return traits_type::eof(); } this->setg(&this->c_, &this->c_, &this->c_ + 1); return traits_type::to_int_type(*this->gptr()); } openvrml_player::uninitialized_plugin_streambuf_map openvrml_player::uninitialized_plugin_streambuf_map_; const boost::shared_ptr<openvrml_player::plugin_streambuf> openvrml_player::uninitialized_plugin_streambuf_map:: find(const std::string & url) const { boost::mutex::scoped_lock lock(this->mutex_); map_t::const_iterator pos = this->map_.find(url); return pos == this->map_.end() ? boost::shared_ptr<plugin_streambuf>() : pos->second; } void openvrml_player::uninitialized_plugin_streambuf_map:: insert(const std::string & url, const boost::shared_ptr<plugin_streambuf> & streambuf) { boost::mutex::scoped_lock lock(this->mutex_); this->map_.insert(make_pair(url, streambuf)); } /** * @brief Erase the first entry corresponding to @p url. * * The map may have multiple entries corresponding to @p url if the same * resource has been requested multiple times. A single call to @c erase will * only remove one of them. * * @return @c true if an entry was removed; @c false otherwise. */ bool openvrml_player::uninitialized_plugin_streambuf_map:: erase(const std::string & url) { boost::mutex::scoped_lock lock(this->mutex_); const map_t::iterator pos = this->map_.find(url); if (pos == this->map_.end()) { return false; } this->map_.erase(pos); return true; } size_t openvrml_player::uninitialized_plugin_streambuf_map::size() const { boost::mutex::scoped_lock lock(this->mutex_); return this->map_.size(); } bool openvrml_player::uninitialized_plugin_streambuf_map::empty() const { boost::mutex::scoped_lock lock(this->mutex_); return this->map_.empty(); } const boost::shared_ptr<openvrml_player::plugin_streambuf> openvrml_player::uninitialized_plugin_streambuf_map::front() const { boost::mutex::scoped_lock lock(this->mutex_); g_assert(!this->map_.empty()); return this->map_.begin()->second; } openvrml_player::plugin_streambuf_map_t openvrml_player::plugin_streambuf_map; --- NEW FILE: bounded_buffer.h --- // -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; -*- // // OpenVRML Mozilla plug-in // Copyright 2004, 2005, 2006 Braden N. McDaniel // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program 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 // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // # ifndef OPENVRML_PLAYER_BOUNDED_BUFFER_H # define OPENVRML_PLAYER_BOUN... [truncated message content] |