diff src/graphics.h.in @ 13281:834f904a3dcb

Add support for full asynchronous graphics toolkit running in a separate thread. Add uicontrol and uipanel implementation. * oct-mutex.h (octave_base_mutex::try_lock): New method. (octave_mutex::try_lock): Likewise. (octave_auto_lock::octave_auto_lock): New argument for blocking/non-blocking locks. (octave_auto_lock::ok): New method to test locking state. (octave_auto_lock::operator bool): Likewise. (octave_thread): New utility class. * oct-mutex.cc (octave_base_mutex::try_lock): New method. (octave_w32_mutex::try_lock): Implement it for Win32. (octave_pthread_mutex::try_lock): Implement it for pthread. (octave_thread): Implement new utility class. * octave.cc (octave_main): Initialize octave_thread. * genprops.awk (emit_get_string_array): New function. (emit_declarations): Use it for string_array_property. * graphics.h.in (base_property::set): New argument to control toolkit notifying. (property::set): Likewise. (string_array_property::string_vector_value): New method. (radio_property::do_set): Add warning about abbreviated radio values. (base_graphics_toolkit::initialize): Returns bool. (graphics_toolkit::initialize): Likewise. (base_graphics_object::toolkit_flag): New member. (base_graphics_object::base_graphics_object): Initialize it. (base_graphics_object::valid_toolkit_object): New method. (base_graphics_object::initialize, base_graphics_object::finalize, base_graphics_object::update): Likewise. (graphics_object::initialize, graphics_object::finalize, graphics_object::update): Likewise. (figure::properties::set_toolkit): Move implementation to source file. (base_properties::get_boundingbox): Add parent size argument for optimization. (figure::properties::get_boundingbox): Likewise. (axes::properties::get_boundingbox): Likewise. (figure::properties::map_from_boundingbox): New utility method. (figure::properties::map_to_boundingbox): Likewise. (axes::properties::get_fontsize_points): New utility method. (text::properties::get_fontsize_points): Likewise. (axes::properties::xlabel, axes::properties::ylabel, axes::properties::zlabel, axes::properties::title): Don't notify toolkit on initialization. (axes::initialize): New method override. (uicontrol): New class. (uipanel): Likewise. (graphics_event::create_callback_event): New static method overload. (graphics_event::create_set_event): New argument to prevent circular behavior when property change is triggered from the toolkit. (gh_manager::post_set): Likewise. (gh_manager::do_post_set): Likewise. (gh_manager::make_graphics_handle): New argument controlling toolkit notify. (gh_manager::make_figure_handle): Likewise. (gh_manager::do_make_graphics_handle): Likewise. (gh_manager::do_make_figure_handle): Likewise. (gh_manager::try_lock): New static method. (gh_manager::execute_listener): Likewise. (gh_manager::enable_event_processing): Likewise. (gh_manager::do_try_lock): New method. (gh_manager::do_execute_listener): Likewise. (gh_manager::do_enable_event_processing): Likewise. (gh_manager::event_processing): New member. (gh_manager::execute_callback): Protect graphics_object access. (gh_manager::auto_lock): Inherits from octave_autolock. Renamed from autolock. (gh_manager::auto_lock::auto_lock): New blocking/non-blocking argument. * graphics.cc (default_control_position, default_control_sliderstep, default_panel_position): New utility functions. (convert_font_size): New utility function. (convert_position): Support 2D-only positions. (lookup_object_name): Support uicontrol and uipanel. (make_graphics_object_from_type): Likewise. (root_figure::init_factory_properties): Likewise. (property_list::set, property_list::lookup): Likewise. (base_property::set): New argument controlling toolkit notifying. (base_property::run_listeners): Call gh_manager::execute_listener, allowing to set a property from another thread and run listeners synchronously with octave. (color_property::do_set): Add warning about abbreviated radio value. (double_radio_property::do_set): Likewise. (finalize_r, initialize_r, xinitialize): New utility functions. (gh_manager::do_free): Calls graphics_object::finalize. (base_graphics_toolkit::initialize): Returns bool. (gnuplot_toolkit::initialize): Likewise. (figure::properties::set_toolkit): Move implementation from header. (figure::properties::get_boundingbox): New argument for parent size. (axes::properties::get_boundingbox): Likewise. (figure::properties::map_from_boundingbox): New utility method. (figure::properties::map_to_boundingbox): Likewise. (axes::properties::update_fontunits): Use convert_font_size. (axes::properties::get_fontsize_points): New utility method. (text::properties::get_fontsize_points): Likewise. (axes::initialize): New method override to trigger initialization of labels and title. (uicontrol): New class. (uipanel): Likewise. (gh_manager::gh_manager): Initialize new event_processing member. (gh_manager::do_make_graphics_handle): New argument controlling toolkit notifying. (gh_manager::do_make_figure_handle): Likewise. (callback_event::callback): New member. (callback_event::callback_event): Initialize it. (callback_event::execute): Use it. (set_event::notify_toolkit): New member. (set_event::set_event): Initialize it. (set_event::execute): Use it. Also allow to set read-only properties. (graphics_event::create_callback_event): New static method overload. (graphics_event::create_set_event): New argument controlling toolkit notifying. (gh_manager::do_restore_gcbo): Rename autolock to auto_lock. (gh_manager::do_post_callback, gh_manager::do_post_function): Likewise. (Fishandle, Fset, Fget, F__get__): Likewise. (F__go_figure__, F__calc_dimensions__, GO_BODY): Likewise. (F__go_delete__, F__go_axes_init__, F__go_handles__, F__go_figure_handles__, Favailable_graphics_toolkits, Faddlistener, Fdellistener, Faddproperty): Likewise. (get_property_from_handle, set_property_in_handle): Likewise. (gh_manager::do_post_set): Likewise. New argument controlling toolkit notifying. (gh_manager::do_execute_listener): New method. (gh_manager::do_enable_event_processing): Likewise. (gh_manager::do_execute_callback): Check callback argument validity. Rename autolock to auto_lock. (gh_manager::do_process_events): Execute drawnow at the end of event processing loop, avoiding recursivity. Maintain the input event hook if gh_manager::event_processing is non zero. (make_graphics_object): Postpone object's toolkit initialization at the end of the object creation. (F__go_figure__): Likewise. (F__go_uicontrol__, F__go_uipanel__): New functions. * __init_fltk__.cc (fltk_graphics_toolkit::initialise): New method. * gl-render.h (opengl_renderer::draw): New argument to identify top-level calls. (opengl_renderer::draw_uipanel): New method. (opengl_renderer::init_gl_context): Likewise. * gl-render.cc (opengl_renderer::draw): New argument to identify top-level calls. Skip uicontrol objects. Handle uipanel objects when top-level. (opengl_renderer::init_gl_context): New method. (opengl_renderer::draw_figure): Use it. (opengl_renderer::draw_uipanel): New method.
author Michael Goffioul <michael.goffioul@gmail.com>
date Thu, 06 Oct 2011 16:44:18 +0100
parents 8bb526fb3349
children cbdefe0ec514
line wrap: on
line diff
--- a/src/graphics.h.in	Wed Oct 05 16:46:16 2011 -0700
+++ b/src/graphics.h.in	Thu Oct 06 16:44:18 2011 +0100
@@ -364,7 +364,8 @@
 
   // Sets property value, notifies graphics toolkit.
   // If do_run is true, runs associated listeners.
-  bool set (const octave_value& v, bool do_run = true);
+  bool set (const octave_value& v, bool do_run = true,
+            bool do_notify_toolkit = true);
 
   virtual octave_value get (void) const
     {
@@ -599,6 +600,8 @@
 
   Cell cell_value (void) const {return Cell (str);}
 
+  string_vector string_vector_value (void) const { return str; }
+
   string_array_property& operator = (const octave_value& val)
     {
       set (val);
@@ -1008,6 +1011,11 @@
           {
             if (match != current_val)
               {
+                if (s.length () != match.length ())
+                  warning_with_id ("Octave:abbreviated-property-match",
+                                   "%s: allowing %s to match %s value %s",
+                                   "set", s.c_str (), get_name ().c_str (),
+                                   match.c_str ());
                 current_val = match;
                 return true;
               }
@@ -1903,8 +1911,9 @@
   octave_value get (void) const
     { return rep->get (); }
 
-  bool set (const octave_value& val)
-    { return rep->set (val); }
+  bool set (const octave_value& val, bool do_run = true,
+            bool do_notify_toolkit = true)
+    { return rep->set (val, do_run, do_notify_toolkit); }
 
   std::string values_as_string (void) const
     { return rep->values_as_string (); }
@@ -2073,10 +2082,10 @@
   // Callback function executed when the given graphics object is
   // created.  This allows the graphics toolkit to do toolkit-specific
   // initializations for a newly created object.
-  virtual void initialize (const graphics_object&)
-    { gripe_invalid ("base_graphics_toolkit::initialize"); }
-
-  void initialize (const graphics_handle&);
+  virtual bool initialize (const graphics_object&)
+    { gripe_invalid ("base_graphics_toolkit::initialize"); return false; }
+
+  bool initialize (const graphics_handle&);
 
   // Callback function executed just prior to deleting the given
   // graphics object.  This allows the graphics toolkit to perform
@@ -2168,11 +2177,11 @@
     { rep->update (h, id); }
 
   // Notifies graphics toolkit that new object was created.
-  void initialize (const graphics_object& go)
-    { rep->initialize (go); }
-
-  void initialize (const graphics_handle& h)
-    { rep->initialize (h); }
+  bool initialize (const graphics_object& go)
+    { return rep->initialize (go); }
+
+  bool initialize (const graphics_handle& h)
+    { return rep->initialize (h); }
 
   // Notifies graphics toolkit that object was destroyed.
   // This is called only for explicitly deleted object. Children are
@@ -2230,6 +2239,7 @@
 // ---------------------------------------------------------------------
 
 class base_graphics_object;
+class graphics_object;
 
 class OCTINTERP_API base_properties
 {
@@ -2298,7 +2308,8 @@
 
   virtual graphics_toolkit get_toolkit (void) const;
 
-  virtual Matrix get_boundingbox (bool /*internal*/ = false) const
+  virtual Matrix get_boundingbox (bool /*internal*/ = false,
+                                  const Matrix& /*parent_pix_size*/ = Matrix ()) const
     { return Matrix (1, 4, 0.0); }
 
   virtual void update_boundingbox (void);
@@ -2442,7 +2453,7 @@
 public:
   friend class graphics_object;
 
-  base_graphics_object (void) : count (1) { }
+  base_graphics_object (void) : count (1), toolkit_flag (false) { }
 
   virtual ~base_graphics_object (void) { }
 
@@ -2603,6 +2614,8 @@
 
   virtual bool valid_object (void) const { return false; }
 
+  bool valid_toolkit_object (void) const { return toolkit_flag; }
+
   virtual std::string type (void) const
   {
     return (valid_object () ? get_properties ().graphics_object_name ()
@@ -2655,9 +2668,35 @@
     }
 
 protected:
+  virtual void initialize (const graphics_object& go)
+    {
+      if (! toolkit_flag)
+        toolkit_flag = get_toolkit ().initialize (go);
+    }
+
+  virtual void finalize (const graphics_object& go)
+    {
+      if (toolkit_flag)
+        {
+          get_toolkit ().finalize (go);
+          toolkit_flag = false;
+        }
+    }
+
+  virtual void update (const graphics_object& go, int id)
+    {
+      if (toolkit_flag)
+        get_toolkit ().update (go, id);
+    }
+
+protected:
   // A reference count.
   int count;
 
+  // A flag telling whether this object is a valid object
+  // in the backend context.
+  bool toolkit_flag;
+
   // No copying!
 
   base_graphics_object (const base_graphics_object&);
@@ -2853,6 +2892,12 @@
                                  listener_mode mode = POSTSET)
     { rep->delete_property_listener (nm, v, mode); }
 
+  void initialize (void) { rep->initialize (*this); }
+  
+  void finalize (void) { rep->finalize (*this); }
+
+  void update (int id) { rep->update (*this, id); }
+
   void reset_default_properties (void)
   { rep->reset_default_properties (); }
 
@@ -3025,15 +3070,7 @@
         return toolkit;
       }
 
-    void set_toolkit (const graphics_toolkit& b)
-    {
-      if (toolkit)
-        toolkit.finalize (__myhandle__);
-      toolkit = b;
-      __graphics_toolkit__ = b.get_name ();
-      __plot_stream__ = Matrix ();
-      mark_modified ();
-    }
+    void set_toolkit (const graphics_toolkit& b);
 
     void set___graphics_toolkit__ (const octave_value& val)
     {
@@ -3058,10 +3095,15 @@
         }
     }
 
-    Matrix get_boundingbox (bool internal = false) const;
+    Matrix get_boundingbox (bool internal = false,
+                            const Matrix& parent_pix_size = Matrix ()) const;
 
     void set_boundingbox (const Matrix& bb);
 
+    Matrix map_from_boundingbox (double x, double y) const;
+
+    Matrix map_to_boundingbox (double x, double y) const;
+
     void update_units (const caseless_str& old_units);
 
     void update_paperunits (const caseless_str& old_paperunits);
@@ -3314,9 +3356,12 @@
     const scaler& get_y_scaler (void) const { return sy; }
     const scaler& get_z_scaler (void) const { return sz; }
 
-    Matrix get_boundingbox (bool internal = false) const;
+    Matrix get_boundingbox (bool internal = false,
+                            const Matrix& parent_pix_size = Matrix ()) const;
     Matrix get_extent (bool with_text = false, bool only_text_height=false) const;
 
+    double get_fontsize_points (double box_pix_height = 0) const;
+
     void update_boundingbox (void)
       {
         if (units_is ("normalized"))
@@ -3456,10 +3501,10 @@
       radio_property zlimmode al , "{auto}|manual"
       radio_property climmode al , "{auto}|manual"
       radio_property alimmode    , "{auto}|manual"
-      handle_property xlabel SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false)
-      handle_property ylabel SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false)
-      handle_property zlabel SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false)
-      handle_property title SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false)
+      handle_property xlabel SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false, false)
+      handle_property ylabel SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false, false)
+      handle_property zlabel SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false, false)
+      handle_property title SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false, false)
       bool_property xgrid , "off"
       bool_property ygrid , "off"
       bool_property zgrid , "off"
@@ -3817,6 +3862,9 @@
 
   void reset_default_properties (void);
 
+protected:
+  void initialize (const graphics_object& go);
+
 private:
   property_list default_properties;
 };
@@ -3902,6 +3950,8 @@
   class OCTINTERP_API properties : public base_properties
   {
   public:
+    double get_fontsize_points (double box_pix_height = 0) const;
+
     // See the genprops.awk script for an explanation of the
     // properties declarations.
 
@@ -4561,6 +4611,162 @@
 
 // ---------------------------------------------------------------------
 
+class OCTINTERP_API uicontrol : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    Matrix get_boundingbox (bool internal = false,
+                            const Matrix& parent_pix_size = Matrix ()) const;
+
+    double get_fontsize_points (double box_pix_height = 0) const;
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES (uicontrol)
+      any_property __object__ , Matrix ()
+      color_property backgroundcolor , color_values (1, 1, 1)
+      callback_property callback , Matrix ()
+      array_property cdata , Matrix ()
+      bool_property clipping , "on"
+      radio_property enable , "{on}|inactive|off"
+      array_property extent rG , Matrix (1, 4, 0.0)
+      radio_property fontangle u , "{normal}|italic|oblique"
+      string_property fontname u , OCTAVE_DEFAULT_FONTNAME
+      double_property fontsize u , 10
+      radio_property fontunits S , "inches|centimeters|normalized|{points}|pixels"
+      radio_property fontweight u , "light|{normal}|demi|bold"
+      color_property foregroundcolor , color_values (0, 0, 0)
+      radio_property horizontalalignment , "{left}|center|right"
+      callback_property keypressfcn , Matrix ()
+      double_property listboxtop , 1
+      double_property max , 1
+      double_property min , 0
+      array_property position , default_control_position ()
+      array_property sliderstep , default_control_sliderstep ()
+      string_array_property string u , ""
+      radio_property style S , "{pushbutton}|togglebutton|radiobutton|checkbox|edit|text|slider|frame|listbox|popupmenu"
+      string_property tooltipstring , ""
+      radio_property units u , "normalized|inches|centimeters|points|{pixels}|characters"
+      row_vector_property value , Matrix (1, 1, 1.0)
+      radio_property verticalalignment , "top|{middle}|bottom"
+    END_PROPERTIES
+
+  private:
+    std::string cached_units;
+
+  protected:
+    void init (void)
+      {
+        cdata.add_constraint ("double");
+        cdata.add_constraint (dim_vector (-1, -1, 3));
+        position.add_constraint (dim_vector (1, 4));
+        sliderstep.add_constraint (dim_vector (1, 2));
+        cached_units = get_units ();
+      }
+    
+    void update_text_extent (void);
+
+    void update_string (void) { update_text_extent (); }
+    void update_fontname (void) { update_text_extent (); }
+    void update_fontsize (void) { update_text_extent (); }
+    void update_fontangle (void) { update_text_extent (); }
+    void update_fontweight (void) { update_text_extent (); }
+    void update_fontunits (const caseless_str& old_units);
+
+    void update_units (void);
+
+  };
+
+private:
+  properties xproperties;
+
+public:
+  uicontrol (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~uicontrol (void) { xproperties.delete_children (); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
+class OCTINTERP_API uipanel : public base_graphics_object
+{
+public:
+  class OCTINTERP_API properties : public base_properties
+  {
+  public:
+    Matrix get_boundingbox (bool internal = false,
+                            const Matrix& parent_pix_size = Matrix ()) const;
+
+    double get_fontsize_points (double box_pix_height = 0) const;
+
+    // See the genprops.awk script for an explanation of the
+    // properties declarations.
+
+    BEGIN_PROPERTIES (uipanel)
+      any_property __object__ , Matrix ()
+      color_property backgroundcolor , color_values (1, 1, 1)
+      radio_property bordertype , "none|{etchedin}|etchedout|beveledin|beveledout|line"
+      double_property borderwidth , 1
+      radio_property fontangle , "{normal}|italic|oblique"
+      string_property fontname , OCTAVE_DEFAULT_FONTNAME
+      double_property fontsize , 10
+      radio_property fontunits S , "inches|centimeters|normalized|{points}|pixels"
+      radio_property fontweight , "light|{normal}|demi|bold"
+      color_property foregroundcolor , color_values (0, 0, 0)
+      color_property highlightcolor , color_values (1, 1, 1)
+      array_property position , default_panel_position ()
+      callback_property resizefcn , Matrix ()
+      color_property shadowcolor , color_values (0, 0, 0)
+      string_property title , ""
+      radio_property titleposition , "{lefttop}|centertop|righttop|leftbottom|centerbottom|rightbottom"
+      radio_property units S , "{normalized}|inches|centimeters|points|pixels|characters"
+    END_PROPERTIES
+
+  protected:
+    void init (void)
+      {
+        position.add_constraint (dim_vector (1, 4));
+      }
+    
+    void update_units (const caseless_str& old_units);
+    void update_fontunits (const caseless_str& old_units);
+
+  };
+
+private:
+  properties xproperties;
+
+public:
+  uipanel (const graphics_handle& mh, const graphics_handle& p)
+    : base_graphics_object (), xproperties (mh, p)
+  {
+    xproperties.override_defaults (*this);
+  }
+
+  ~uipanel (void) { xproperties.delete_children (); }
+
+  base_properties& get_properties (void) { return xproperties; }
+
+  const base_properties& get_properties (void) const { return xproperties; }
+
+  bool valid_object (void) const { return true; }
+};
+
+// ---------------------------------------------------------------------
+
 octave_value
 get_property_from_handle (double handle, const std::string &property,
                           const std::string &func);
@@ -4632,14 +4838,19 @@
       create_callback_event (const graphics_handle& h,
                              const std::string& name,
                              const octave_value& data = Matrix ());
+  
+  static graphics_event
+      create_callback_event (const graphics_handle& h,
+                             const octave_value& cb,
+                             const octave_value& data = Matrix ());
 
   static graphics_event
       create_function_event (event_fcn fcn, void *data = 0);
 
   static graphics_event
-      create_set_event (const graphics_handle& h,
-                        const std::string& name,
-                        const octave_value& value);
+      create_set_event (const graphics_handle& h, const std::string& name,
+                        const octave_value& value,
+                        bool notify_toolkit = true);
 private:
   base_graphics_event *rep;
 };
@@ -4698,17 +4909,21 @@
 
   static graphics_handle
   make_graphics_handle (const std::string& go_name,
-                        const graphics_handle& parent, bool do_createfcn = true)
+                        const graphics_handle& parent, bool do_createfcn = true,
+                        bool do_notify_toolkit = true)
   {
     return instance_ok ()
-      ? instance->do_make_graphics_handle (go_name, parent, do_createfcn)
+      ? instance->do_make_graphics_handle (go_name, parent, do_createfcn,
+                                           do_notify_toolkit)
       : graphics_handle ();
   }
 
-  static graphics_handle make_figure_handle (double val)
+  static graphics_handle make_figure_handle (double val,
+                                             bool do_notify_toolkit = true)
   {
     return instance_ok ()
-      ? instance->do_make_figure_handle (val) : graphics_handle ();
+      ? instance->do_make_figure_handle (val, do_notify_toolkit)
+      : graphics_handle ();
   }
 
   static void push_figure (const graphics_handle& h)
@@ -4740,30 +4955,50 @@
       instance->do_lock ();
   }
 
+  static bool try_lock (void)
+  {
+    if (instance_ok ())
+      return instance->do_try_lock ();
+    else
+      return false;
+  }
+
   static void unlock (void)
   {
     if (instance_ok ())
       instance->do_unlock ();
   }
-
+  
   static Matrix figure_handle_list (void)
   {
     return instance_ok () ? instance->do_figure_handle_list () : Matrix ();
   }
 
+  static void execute_listener (const graphics_handle& h,
+                                const octave_value& l)
+  {
+    if (instance_ok ())
+      instance->do_execute_listener (h, l);
+  }
+
   static void execute_callback (const graphics_handle& h,
                                 const std::string& name,
                                 const octave_value& data = Matrix ())
   {
-    graphics_object go = get_object (h);
-
-    if (go.valid_object ())
+    octave_value cb;
+
+    if (true)
       {
-        octave_value cb = go.get (name);
-
-        if (! error_state)
-          execute_callback (h, cb, data);
+        gh_manager::auto_lock lock;
+
+        graphics_object go = get_object (h);
+
+        if (go.valid_object ())
+          cb = go.get (name);
       }
+
+    if (! error_state)
+      execute_callback (h, cb, data);
   }
 
   static void execute_callback (const graphics_handle& h,
@@ -4781,19 +5016,18 @@
     if (instance_ok ())
       instance->do_post_callback (h, name, data);
   }
-
+  
   static void post_function (graphics_event::event_fcn fcn, void* data = 0)
   {
     if (instance_ok ())
       instance->do_post_function (fcn, data);
   }
 
-  static void post_set (const graphics_handle& h,
-                        const std::string& name,
-                        const octave_value& value)
+  static void post_set (const graphics_handle& h, const std::string& name,
+                        const octave_value& value, bool notify_toolkit = true)
   {
     if (instance_ok ())
-      instance->do_post_set (h, name, value);
+      instance->do_post_set (h, name, value, notify_toolkit);
   }
 
   static int process_events (void)
@@ -4806,6 +5040,12 @@
     return (instance_ok () ?  instance->do_process_events (true) : 0);
   }
 
+  static void enable_event_processing (bool enable = true)
+    {
+      if (instance_ok ())
+        instance->do_enable_event_processing (enable);
+    }
+
   static bool is_handle_visible (const graphics_handle& h)
   {
     bool retval = false;
@@ -4819,18 +5059,21 @@
   }
 
 public:
-  class autolock
+  class auto_lock : public octave_autolock
   {
   public:
-    autolock (void) { lock (); }
-
-    ~autolock (void) { unlock (); }
+    auto_lock (bool wait = true)
+      : octave_autolock (instance_ok ()
+                         ? instance->graphics_lock
+                         : octave_mutex (),
+                         wait)
+      { }
 
   private:
 
     // No copying!
-    autolock (const autolock&);
-    autolock& operator = (const autolock&);
+    auto_lock (const auto_lock&);
+    auto_lock& operator = (const auto_lock&);
   };
 
 private:
@@ -4868,6 +5111,9 @@
   // The stack of callback objects.
   std::list<graphics_object> callback_objects;
 
+  // A flag telling whether event processing must be constantly on.
+  int event_processing;
+
   graphics_handle get_handle (const std::string& go_name);
 
   void do_free (const graphics_handle& h);
@@ -4887,9 +5133,10 @@
   }
 
   graphics_handle do_make_graphics_handle (const std::string& go_name,
-                                           const graphics_handle& p, bool do_createfcn);
-
-  graphics_handle do_make_figure_handle (double val);
+                                           const graphics_handle& p, bool do_createfcn,
+                                           bool do_notify_toolkit);
+
+  graphics_handle do_make_figure_handle (double val, bool do_notify_toolkit);
 
   Matrix do_handle_list (void)
   {
@@ -4928,18 +5175,22 @@
 
   void do_lock (void) { graphics_lock.lock (); }
 
+  bool do_try_lock (void) { return graphics_lock.try_lock (); }
+
   void do_unlock (void) { graphics_lock.unlock (); }
 
+  void do_execute_listener (const graphics_handle& h, const octave_value& l);
+
   void do_execute_callback (const graphics_handle& h, const octave_value& cb,
                             const octave_value& data);
 
   void do_post_callback (const graphics_handle& h, const std::string name,
                          const octave_value& data);
-
+  
   void do_post_function (graphics_event::event_fcn fcn, void* fcn_data);
 
   void do_post_set (const graphics_handle& h, const std::string name,
-                    const octave_value& value);
+                    const octave_value& value, bool notify_toolkit = true);
 
   int do_process_events (bool force = false);
 
@@ -4952,6 +5203,8 @@
   void do_restore_gcbo (void);
 
   void do_post_event (const graphics_event& e);
+
+  void do_enable_event_processing (bool enable = true);
 };
 
 void get_children_limits (double& min_val, double& max_val,